xor问题的小结(HDU_5269 && HDU_5270 && NEU_1600)

来源:互联网 发布:如皋淘宝 编辑:程序博客网 时间:2024/06/01 08:41

xor就是一个位运算的问题,做题的时候按二进制拆开,然后一位一位搞就好了,HDU_5269就是把数拆成二进制,然后维护一颗字母树,查找公共前缀的问题,(中间有几个小trick,秦总是dfs过的,然而我并没有去认真想怎么搞)。HDU_5270这题也是拆成2^i来搞的,但是题解上面说是归并搞(并没有看懂),如果按位直接从低位到高位来搞的话,不就是一个基数排序嘛,然后就是nlog(A)+nlogn的复杂度。NEU这道题是四省赛的题目,感觉可能就是HDU_5269的难度,BC第二题吧,就是把数拆开来,[l,r]这之间的数的第i位有多少个1。然后附上代码

HDU_5269:

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#define ll  long long#define FOR(i,x,y)  for(int i = x;i < y;i ++)#define IFOR(i,x,y) for(int i = x;i > y;i --)#define MOD 998244353using namespace std;const int MAXN = 50005;int ch[MAXN*32][2];int val[MAXN*32],sz;int num[32],cnt[32],n,m[MAXN];void init(){    sz = 1;    ch[0][1] = ch[0][0] = 0;}void translate(int s){    FOR(i,0,32){        num[i] = s%2;        s /= 2;    }}void insert(int* num,int v){    int u = 0;    FOR(i,0,32){        int c = num[i];        if(!ch[u][c]){            ch[sz][0] = ch[sz][1] = 0;            val[sz] = v;            ch[u][c] = sz++;        }        else{            val[ch[u][c]] += v;        }        u = ch[u][c];    }}void find(int* num){    int u = 0;    FOR(i,0,32){        int c = num[i];        cnt[i] = val[ch[u][c]];        u = ch[u][c];    }}int main(){    //freopen("test.in","r",stdin);    int t,tCase = 0;    scanf("%d",&t);    while(t--){        init();        scanf("%d",&n);        FOR(i,0,n){            scanf("%d",&m[i]);            translate(m[i]);            insert(num,1);        }        ll ans = 0;        FOR(i,0,n){            translate(m[i]);            find(num);            IFOR(i,30,-1){                ll tem = cnt[i] - cnt[i+1];                if(!tem)    continue;                tem = (tem*(1<<(i+1))) % MOD;                ans += tem;                ans %= MOD;            }            ll tem = n - cnt[0];            ans += tem;            ans %= MOD;        }        printf("Case #%d: %I64d\n",++tCase,ans);    }    return 0;}

HDU_5270:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <vector>#define ll  long long#define FOR(i,x,y)  for(int i = x;i < y;i ++)#define IFOR(i,x,y) for(int i = x;i > y;i --)using namespace std;const int N = 100005;ll a[N],b[N],x[N],y[N],px[N],py[N],p0[N],p1[N],z0[N],z1[N];int n;int Scan(){    int res = 0, ch, flag = 0;    if((ch = getchar()) == '-')        flag = 1;    else if(ch >= '0' && ch <= '9')        res = ch - '0';    while((ch = getchar()) >= '0' && ch <= '9' )        res = res * 10 + ch - '0';    return flag ? -res : res;}ll ll_Scan(){    ll res = 0, ch, flag = 0;    if((ch = getchar()) == '-')        flag = 1;    else if(ch >= '0' && ch <= '9')        res = ch - '0';    while((ch = getchar()) >= '0' && ch <= '9' )        res = res * 10 + ch - '0';    return flag ? -res : res;}void new_sort(ll* c,ll* p,ll* z,ll lowbit){    ll MOD = lowbit << 1;    int cnt0 = 0,cnt1 = 0;    FOR(i,0,n){        if(c[p[i]]&lowbit){            z1[cnt1] = c[p[i]] % MOD;            p1[cnt1++] = p[i];        }        else{            z0[cnt0] = c[p[i]] % MOD;            p0[cnt0++] = p[i];        }    }    FOR(i,0,cnt0){        p[i] = p0[i];        z[i] = z0[i];    }    FOR(i,0,cnt1){        p[i+cnt0] = p1[i];        z[i+cnt0] = z1[i];    }}ll find_ans(ll lowbit){    int j1 = 0,j2 = 0,j3 = 0;    while(j1 < n && x[0] + y[j1] < lowbit){        j1 ++;    }    while(j2 < n && x[0] + y[j2] < (lowbit*2)){        j2++;    }    while(j3 < n && x[0] + y[j3] < (lowbit*3)){        j3++;    }    int c = (n + j2 - j1 - j3) % 2;    FOR(i,1,n){        while(j1 >= 1 && x[i] + y[j1-1] >= lowbit){            j1--;        }        while(j2 >= 1 && x[i] + y[j2-1] >= lowbit*2){            j2--;        }        while(j3 >= 1 && x[i] + y[j3-1] >= lowbit*3){            j3--;        }        c = c ^ ((n + j2 - j1 - j3) % 2);    }    if(c)   return lowbit;    else    return 0;}void solve(){    ll ans = 0;    FOR(i,0,n){        px[i] = py[i] = i;    }    FOR(i,0,62){        ll lowbit = (ll)1 << i;        new_sort(a,px,x,lowbit);        new_sort(b,py,y,lowbit);        ans += find_ans(lowbit);    }    printf("%I64d\n",ans);}int main(){    //freopen("test.in","r",stdin);    int t,tCase = 0;    t = Scan();    while(t--){        printf("Case #%d: ",++tCase);        n = Scan();        FOR(i,0,n){            a[i] = ll_Scan();        }        FOR(i,0,n){            b[i] = ll_Scan();        }        solve();    }    return 0;}

NEU_1600:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#define ll  long long#define FOR(i,x,y)  for(int i = x;i < y;i ++)#define IFOR(i,x,y) for(int i = x;i > y;i --)#define MOD 1000007 using namespace std; const int M = 100005;const int N = 100005; int cnt[N][35],n,m,sum[N]; int main(){    //freopen("test.in","r",stdin);    int t,tCase = 0;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        printf("Case $%d:\n",++tCase);        FOR(i,0,n+1){            FOR(j,0,16){                cnt[i][j] = 0;            }        }        int res = (1<<16),num;        int b_ans = 0;        FOR(i,1,n+1){            scanf("%d",&num);            if(num >= res){                int tem = num >> 16;                tem = tem << 16;                b_ans += tem;                b_ans %= MOD;                num = num - tem;            }            FOR(sz,0,16){                int c = num % 2;                if(c)   cnt[i][sz] = cnt[i-1][sz] + 1;                else cnt[i][sz] = cnt[i-1][sz];                num >>= 1;            }        }        while(m--){            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            int ans = b_ans;            FOR(i,0,16){                int c = z % 2;                int tem = 1<<i;                if(!c)   ans += tem * (cnt[y][i] - cnt[x-1][i]);                else    ans += tem * ((y-x+1) - (cnt[y][i] - cnt[x-1][i]));                z >>= 1;                ans %= MOD;            }            printf("%d\n",ans);        }    }    return 0;}


0 0