标签:nbsp scanf main 枚举 异或运算 数据 可持久化trie树 线段 algo
一看数据范围,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 }
bzoj4103[Thu Summer Camp 2015]异或运算(可持久化trie树)
标签:nbsp scanf main 枚举 异或运算 数据 可持久化trie树 线段 algo
原文地址:https://www.cnblogs.com/lnxcj/p/10029811.html