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\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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。