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 998244353 using 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 ",++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 ",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: ",++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 ",ans); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。