1. 程式人生 > >bzoj4103[Thu Summer Camp 2015]異或運算(可持久化trie樹)

bzoj4103[Thu Summer Camp 2015]異或運算(可持久化trie樹)

一看資料範圍,n很小m很大,對長的那一維建可持久化線段樹,另一維暴力列舉

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n,m,cnt,tot,p;
 7 int rt[300005];
 8 int x[2005];
 9 int y[300005];
10 struct Trie{
11     int son[2];
12     int siz;
13
}tr[10000005]; 14 void insert(int fr,int tim,int s){ 15 int now=rt[tim]=++tot; 16 for(int i=30;i>=0;i--){ 17 tr[now].son[!((s>>i)&1)]=tr[fr].son[!((s>>i)&1)]; 18 tr[now].son[(s>>i)&1]=++tot; 19 now=tr[now].son[(s>>i)&1]; 20 fr=tr[fr].son[(s>>i)&1
]; 21 tr[now].siz=tr[fr].siz+1; 22 } 23 } 24 int query(int u,int d,int l,int r,int k){ 25 int now[2005];int fr[2005]; 26 int ret=0; 27 for(int i=u;i<=d;i++){ 28 now[i]=rt[r]; 29 fr[i]=rt[l-1]; 30 } 31 for(int i=30;i>=0;i--){ 32 int sum=0
; 33 for(int j=u;j<=d;j++){ 34 int s=x[j]; 35 sum+=tr[tr[now[j]].son[!((s>>i)&1)]].siz-tr[tr[fr[j]].son[!((s>>i)&1)]].siz; 36 } 37 if(sum>=k){ 38 ret|=(1<<i); 39 for(int j=u;j<=d;j++){ 40 int s=x[j]; 41 now[j]=tr[now[j]].son[!((s>>i)&1)]; 42 fr[j]=tr[fr[j]].son[!((s>>i)&1)]; 43 } 44 }else{ 45 k-=sum; 46 for(int j=u;j<=d;j++){ 47 int s=x[j]; 48 now[j]=tr[now[j]].son[(s>>i)&1]; 49 fr[j]=tr[fr[j]].son[(s>>i)&1]; 50 } 51 } 52 } 53 return ret; 54 } 55 int main(){ 56 scanf("%d%d",&n,&m); 57 for(int i=1;i<=n;i++){ 58 scanf("%d",&x[i]); 59 } 60 insert(0,0,0); 61 for(int i=1;i<=m;i++){ 62 scanf("%d",&y[i]); 63 insert(rt[i-1],i,y[i]); 64 } 65 scanf("%d",&p); 66 for(int i=1;i<=p;i++){ 67 int u,d,l,r,k; 68 scanf("%d%d%d%d%d",&u,&d,&l,&r,&k); 69 int ans=query(u,d,l,r,k); 70 printf("%d\n",ans); 71 } 72 return 0; 73 }