zoukankan      html  css  js  c++  java
  • CF1054D Solution

    题目链接

    题解

    因为异或结果( ot=0)的情况过多,我们可以转为考虑结果(=0)的情况,用总数减去这些区间即可。每一个数都可以和包括自己的(n)个数组为区间,因此总数(=frac{n(n+1)}{2})

    至于如何求结果(=0)的方案数,可以想到前缀和,但枚举左右端点需要(O(n^2))的时间。进一步思考,我们只需要区间数量而不需要求出具体的区间。因为异或的逆运算是其本身,所以当(sum_{r}oplus sum_{l-1}=0)时区间([l,r])和为(0),因此对于每一个(r)(sum_{l-1}=sum_r)(l)的个数即为右端点为(r)且区间异或和为(0)的区间个数,具体实现用(map[i])记录(sum=i)的元素个数即可。

    此外还有变换操作,易得该操作的实质是(a_ioplus 2^k-1)。对于(a_i),在变换与不变换中取最小值即可。

    又及:当前缀和(0)的时候是不可以取([1,r])区间的,因此(map[0]=1)(WA的教训)。

    AC代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e5+10;
    int a[N];
    map<int,int> mp;
    signed main()
    {
    	int n,k,lst=0,ans=0;
    	scanf("%lld%lld",&n,&k);
    	int mov=(1<<k)-1; mp[0]=1;
    	for(int i=1;i<=n;i++) 
    	{
    		scanf("%lld",&a[i]);
    		int qwq=lst^a[i]; int qaq=qwq^mov;//qwq:不变换,qaq:变换
    		if(mp[qwq]<mp[qaq]) {ans+=(mp[qwq]++); lst=qwq;}//不变换更优
    		else {ans+=(mp[qaq]++); lst=qaq;}//变换更优
    	}
    	printf("%lld",n*(n+1)/2-ans);
    	return 0;
    }
    
  • 相关阅读:
    jquery1.9之学习笔记
    ERROR: Removing 'hello': Device or resource busy
    windows虚拟机性能调整
    kvm虚拟机控制台登录配置
    KVM虚拟机的管理
    window kvm 虚拟机的创建
    kvm虚拟化环境的搭建
    C实现哈希表
    哲学家就餐问题 C语言实现
    Linux面试题
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14257463.html
Copyright © 2011-2022 走看看