[BZOJ4103] 异或运算

抱佛脚...

首先想到查找第K大的异或值可以按为确定,方法类似平衡树查第K大

然后,就跑到前缀和上去死磕了...

然而明明一颗可持久化trie树就可以解决的...

然后n*p*32^2过了以后表示老夫怎么这么慢阿,,,于是发现别人是n*p*32的,每次记下来就好,不用再跑一遍的...

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mp make_pair
 4 #define fir first
 5 #define sec second
 6 #define maxn 1005
 7 #define maxm 300005
 8 #define maxnd 10000005
 9 #define maxl 32
10 int A[maxn],B[maxm];
11 int nd,root[maxm],trie[maxnd][2],mrk[maxnd];
12 pair<int,int>at[maxn];
13 int read(){
14     int tmp=0; char ch=0;
15     while(ch<'0'||ch>'9')ch=getchar();
16     while(ch>='0'&&ch<='9')tmp=tmp*10+ch-'0',ch=getchar();
17     return tmp;
18 }
19 void insert(int pos){
20     int x=++nd,y=root[pos-1];
21     root[pos]=x;
22     for(int i=maxl-1;i>=0;i--){
23         int val=(B[pos]>>i)&1;
24         trie[x][val^1]=trie[y][val^1];
25         mrk[x]=mrk[y]+1;
26         trie[x][val]=++nd;
27         x=trie[x][val],y=trie[y][val];
28     }
29     mrk[x]=mrk[y]+1;
30 }
31 int solve(int u,int d,int l,int r,int k){   
32     int ans=0;
33     for(int j=u;j<=d;j++)
34         at[j]=mp(root[r],root[l-1]);
35     for(int i=maxl-1;i>=0;i--){
36         int cnt=0;
37         for(int j=u;j<=d;j++){
38             int val=(A[j]>>i)&1;
39             cnt+=mrk[trie[at[j].fir][val^1]]-mrk[trie[at[j].sec][val^1]];
40         }
41         if(cnt>=k){
42             ans+=1<<i;
43             for(int j=u;j<=d;j++){
44                 int val=(A[j]>>i)&1;
45                 at[j]=mp(trie[at[j].fir][val^1],trie[at[j].sec][val^1]);
46             }
47         }
48         else{
49             k-=cnt;
50             for(int j=u;j<=d;j++){
51                 int val=(A[j]>>i)&1;
52                 at[j]=mp(trie[at[j].fir][val],trie[at[j].sec][val]);
53             }
54         }
55     }
56     return ans;
57 }
58 int main(){
59     int n,m,q,u,d,l,r,k;
60     n=read(),m=read();
61     for(int i=1;i<=n;i++)A[i]=read();
62     for(int i=1;i<=m;i++){
63         B[i]=read();
64         insert(i);
65     }
66     q=read();
67     for(int i=1;i<=q;i++){
68         u=read(),d=read(),l=read(),r=read(),k=read();
69         printf("%d\n",solve(u,d,l,r,k));
70     }
71     return 0;
72 }
View Code

 

posted @ 2016-05-29 10:16  Ngshily  阅读(278)  评论(0编辑  收藏  举报