Codeforces Round #626 D. Present

D. Present

题目大意:给你一个大小是n的序列,求两两之间相加进行异或之后的答案。

这个题目我并没有想到怎么写,有点偷懒于是就去看了题解。。

题解很套路。。。

题解:

因为这个是用到了异或,所以不可避免的肯定要用到二进制。

所以考虑进行拆位,当我要考虑第 \(i\) 位,那么比这一位高的都不会产生影响,所以对所有的数取模处理一下,然后再枚举每一个数满足条件的一个区间,这个可以二分来解决。

因为每一个数的区间是 \(0=<a_i<=2^{i+1}-1\),所以之和的区间是 \(0<=a_i<=2^{i+2}-2\)

条件:

  • 两个数之和在 \([2^i,2^{i+1}-1]\)
  • 两个数之和在 \([2^{i+1}+2^i,2^{i+2}-2]\)
//我还以为会wa,比较复杂度我大致算了一下可能会超时一点点。。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=4e5+7;
typedef long long ll;
int a[maxn],bit[maxn],n;
int Ans[maxn];
int judgemin(int sum,int x,int y){
//    printf("min sum=%d x=%d\n",sum,x);
    int l=1,r=y,ans=inf;
    while(l<=r){
        int mid=(l+r)>>1;
//        printf("mid=%d bit=%d\n",mid,bit[mid]);
        int all=bit[mid]+x;
        if(all>=sum) ans=mid,r=mid-1;
        else l=mid+1;
    }
    return ans;
}
int judgemax(int sum,int x,int y){
//    printf("max sum=%d x=%d\n",sum,x);
    int l=1,r=y,ans=0;
    while(l<=r){
        int mid=(l+r)>>1;
//        printf("bit[%d]=%d\n",mid,bit[mid]);
        int all=bit[mid]+x;
        if(all<=sum) ans=mid,l=mid+1;
        else r=mid-1;
    }
    return ans;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=0;i<=25;i++){
        int mod=1<<(i+1),ans=0;
//        printf("mod=%d\n",mod);
        for(int j=1;j<=n;j++) bit[j]=a[j]%mod;
        sort(bit+1,bit+1+n);
        for(int j=1;j<=n;j++){
            int x=bit[j];
//            printf("j=%d bit[%d]=%d\n",j,j,bit[j]);
            int lc=judgemin(1<<i,x,j-1),rc=judgemax(mod-1,x,j-1);
//            printf("fi lc=%d rc=%d\n",lc,rc);
            ans+=max(0,rc-lc+1);
            lc=judgemin((1<<(i+1))+(1<<i),x,j-1),rc=judgemax((1<<(i+2))-2,x,j-1);
//            printf("se lc=%d rc=%d\n",lc,rc);
            ans+=max(0,rc-lc+1);
        }
        Ans[i]=(ans&1);
//        printf("Ans[%d]=%d\n",i,Ans[i]);
    }
    int ans=0;
    for(int i=25;i>=0;i--){
        ans=ans*2+Ans[i];
    }
    printf("%d\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/EchoZQN/p/12572918.html