Codeforces&Atcoder三月补题

1.Codeforces Round #626 Div2

D. Present(位运算+二分)

题意:

给一个数组,求(a1+a2)^(a1+a3)^...(a1+an)^(a2+ a3)^...(a2+an)....^(an-1+an)

思路:

可以看出答案中每一位的贡献都是独立的,所以我们计算每一位的贡献

对于第i位,因为i位之后的数对第i位不会产生影响,所以我们分别对a[i]%(1<<(i+1)),取模之后的任意两数和不会超过2i+2-2

 还有一个很显而易见的事就是任意两数和第i位上为1的个数如果是奇数的话第i位就会对答案产生贡献,所以我们就只要查找有多少对符合要求的数

 如果两数之和在[2i , 2i+1) 与 [2i+1+2, 2i+2-2] 这两个区间之内,第i位上就会为1

 之后就是一个比较经典的二分问题了,就是对于一个数找有多少个符合相加满足一定条件的数的个数,对于每个数二分一下即可

#include<iostream>
#include<algorithm>
 using namespace std;
 const int maxn=4e5+10;
 int a[maxn],b[maxn];
 int main()
 {
     int n,ans=0;
     scanf("%d",&n);
     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
     for(int i=0;i<=24;i++){
         int cnt=0;
         for(int j=1;j<=n;j++) b[j]=a[j]%(1<<(i+1));
        sort(b+1,b+1+n);
        for(int j=1;j<=n;j++){
            int l=lower_bound(b+1,b+1+n,(1<<i)-b[j])-b;
            l=max(l,j+1);
            int r=lower_bound(b+1,b+1+n,(1<<(i+1))-b[j])-b;
            r=max(r,j+1);
            cnt+=(r-l); 
        }
        for(int j=1;j<=n;j++){
            int l=lower_bound(b+1,b+1+n,(1<<i)+(1<<(i+1))-b[j])-b;
            l=max(l,j+1);
            int r=n+1;
            cnt+=(r-l); 
        }
        if(cnt%2) ans+=1<<i;
     }
    cout<<ans<<endl;
    return 0;
 }
View Code

 

 

猜你喜欢

转载自www.cnblogs.com/overrate-wsj/p/12444734.html