TOJ 4114 Evaluate Xor

本文详细解析了一道ACM编程挑战题目,通过使用树状数组(Binary Indexed Tree, BIT)来解决区间求和问题,并实现了高效的查找特定位数中1的数量,以找到答案的二进制表示中的高位。

For AC this problem ,I consult AClavin's code ,For clearly knowing the code's operational principle.I research the code ...hours.Too hard to understanding.

The portal:http://acm.tju.edu.cn/toj/showp4114.html

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>

const int N = 1e5+5;
const int M = 1e6+5;

int a[N];
int Bit[M<<1];

void Insert(int x,int value){
    for(int i = x ; i<= M ; i+= i & (-i)){
        Bit[i] += value;
    }
}

int Query(int x){
    int ret = 0;
    if(x <= 0) return ret;
    for(int i = x; i ; i -= i & (-i)){
        ret += Bit[i];
    }
    return ret;
}

void Deal_with(){
    int T;
    scanf("%d",&T);
    memset(Bit,0,sizeof(Bit));
    while(T--){
        int n;
        scanf("%d",&n);
        int tempa;
        a[0] = 0;
        for(int i=1;i<=n;i++){
            scanf("%d",&tempa);
            a[i] = a[i-1] + tempa;
        }
        int up = floor(log(a[n])/log(2.0));
        //up is the floor of bit of answer.
        int res = 0;
        for(int l = up ;l >= 0;l--){
            int lim = 1 << l , Mod = lim << 1;
            int tmp = 0;
            // tmp calculate there is how many '1' in this bit.
            Insert(1,1);
            //Add 1 for every Bit array's member just for avoid tree_array query '0'.
            //Insert(1,1) is Insert 0 to Bit array , the value of '0' is 1;
            for(int i=1;i<=n;i++){
                int s = (a[i] + 1) % Mod;
                int e = (a[i] + lim) % Mod;
                // when bit is '1' , lim = 2 ,mod = 4;
                // Array a = 1,3,5,6;
                if(s > e){
                    tmp += i - Query(s);
                    //Mimic to get a higher bit digital.
                    // 6 = (110); a[i] = (10); s = (10) ;if you can find ki (10) .. (11);a[i] - ki '1' bit will change to 1.
                    tmp += Query(e+1);
                    //Mimic a[i] - a[k] k = 1..i Have or not i bit digital.
                    // 3 = (11);  a[i] = (11); e = (01) ;if you can find ki (00) ... (01);a[i] - ki '1' bit will still be '1'.
                }
                else {
                    tmp += Query(e+1) - Query(s);
                    //Mimic to get a higher bit digital.
                    //5 = (101) ;a[i] = (01); s = (01) ; e = (11) ;if you can find ki (01)..(11);a[i] -ki '1' bit will change to 1.
                }
                Insert(a[i]+1,1);
            }
            if(tmp & 1) res += lim;
            Insert(1,-1);
            for(int i=1;i<=n;i++){
                Insert(a[i]+1,-1);
                a[i] &= (lim - 1);
            }
        }
        printf("%d\n",res);
    }
}

int main(void){
    //freopen("a.in","r",stdin);
    Deal_with();
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值