[Luogu] P3760 XOR and (weight tree array)

  topic link

  After I declare it again, when I see the bit operation, I will definitely want to split it into each bit operation for the first time.

  This question is to have a prefix and sum[], and then ask you to find how many pairs of i,j satisfy sum[i]-sum[j] in each bit and that bit is 1

  Consider how to subtract 1

  If sum[i] is 1 in this bit, then j is required to be 0 and the number in front of sum[i] is less than the number in front of sum[j], so that it will not reduce the bit, put sum[i] The 1 of this one is gone

  If it is 0, the same

  Consider maintaining a tree-like array of weights.

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<cstdlib>
#define maxn 1000010
using namespace std;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num = num * 10 + ch - 0 ' ;
        ch=getchar();
    }
    return num*f;
}

inline int low(int x){    return x&(-x);    }

you are everything;
int sum [maxn];

struct Tree{
    int tree[maxn];
    void clear(){    memset(tree,0,sizeof(tree));    }
    inline void add(int pos){
        while(pos<=tot){
            tree[pos]++;
            pos+=low(pos);
        }
    }
    inline int ask(int pos){
        int ans=0;
        while(pos>0){
            ans += tree[pos];
            pos-=low(pos);
        }
        return ans;
    }
}zero,one;

int main(){
    int n=read();
    for(int i=1;i<=n;++i)    sum[i]=sum[i-1]+read();
    tot=sum[n]+1;
    int ans=0;
    for(int i=0;(1<<i)<=tot;++i){
        zero.clear();one.clear();
        int cnt=0;
        zero.add(1);
        for(int j=1;j<=n;++j){
            int now=(sum[j]%(1<<i))+1;
            if(((sum[j]>>i)&1)==1){
                cnt+=zero.ask(now);
                cnt+=one.ask(tot)-one.ask(now);
                one.add(now);
            }
            else{
                cnt+=zero.ask(tot)-zero.ask(now);
                cnt+=one.ask(now);
                zero.add(now);
            }
        }
        //printf("%d %d\n",i,cnt);
        if(cnt&1)    ans+=1<<i;
    }
    printf("%d",ans);
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325249204&siteId=291194637