您的位置:首页 > 其它

【BZOJ 4103】 4103: [Thu Summer Camp 2015]异或运算 (可持久化Trie)

2017-04-08 14:47 337 查看

4103: [Thu Summer Camp 2015]异或运算

Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 474 Solved: 258

Description

给定长度为n的数列X={x1,x2,...,xn}和长度为m的数列Y={y1,y2,...,ym},令矩阵A中第i行第j列的值Aij=xi xor yj,每次询问给定矩形区域i∈[u,d],j∈[l,r],找出第k大的Aij。

Input

第一行包含两个正整数n,m,分别表示两个数列的长度

第二行包含n个非负整数xi
第三行包含m个非负整数yj
第四行包含一个正整数p,表示询问次数
随后p行,每行均包含5个正整数,用来描述一次询问,每行包含五个正整数u,d,l,r,k,含义如题意所述。

Output

共p行,每行包含一个非负整数,表示此次询问的答案。

Sample Input

3 3

1 2 4

7 6 5

3

1 2 1 2 2

1 2 1 3 4

2 3 2 3 4

Sample Output

6

5

1

HINT

对于100%的数据,0<=Xi,Yj<2^31,

1<=u<=d<=n<=1000,

1<=l<=r<=m<=300000,

1<=k<=(d-u+1)*(r-l+1),

1<=p<=500

Source

鸣谢佚名上传



【分析】

  要膜一膜Po姐:

1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<algorithm>
6 using namespace std;
7 #define Maxn 1010
8 #define Maxm 300010
9 #define Maxd 30
10
11 int a[Maxn];
12
13 int rt[Maxm],tot=0;
14 struct node {int lc,rc,cnt;}tr[Maxm*32];
15
16 void add(int id,int x)
17 {
18     rt[id]=++tot;int y=rt[id-1];
19     int nw=rt[id];
20     for(int i=Maxd;i>=0;i--)
21     {
22         int ind=x>>i;x&=(1<<i)-1;
23         if(!ind)
24         {
25             tr[nw].lc=++tot;
26             tr[tot].cnt=tr[tr[y].lc].cnt+1;
27             tr[nw].rc=tr[y].rc;
28             nw=tr[nw].lc;y=tr[y].lc;
29         }
30         else
31         {
32             tr[nw].rc=++tot;
33             tr[tot].cnt=tr[tr[y].rc].cnt+1;
34             tr[nw].lc=tr[y].lc;
35             nw=tr[nw].rc;y=tr[y].rc;
36         }
37     }
38 }
39
40 int nl[Maxn],nr[Maxn];
41 int query(int ll,int rr,int l,int r,int k)
42 {
43     int ans=0;
44     // l=rt[l-1];r=rt[r];
45     for(int i=ll;i<=rr;i++) nl[i]=rt[l-1],nr[i]=rt[r];
46     for(int i=Maxd;i>=0;i--)
47     {
48         int x=0;
49         for(int j=ll;j<=rr;j++)
50         {
51             int y=a[j]&(1<<i);y>>=i;
52             if(y==0) x+=tr[tr[nr[j]].lc].cnt-tr[tr[nl[j]].lc].cnt;
53             else x+=tr[tr[nr[j]].rc].cnt-tr[tr[nl[j]].rc].cnt;
54         }
55         if(x>=k)
56         {
57             l=tr[l].lc;r=tr[r].lc;
58             for(int j=ll;j<=rr;j++)
59             {
60                 int y=a[j]&(1<<i);y>>=i;
61                 if(y==0) nl[j]=tr[nl[j]].lc,nr[j]=tr[nr[j]].lc;
62                 else nl[j]=tr[nl[j]].rc,nr[j]=tr[nr[j]].rc;
63             }
64         }
65         else
66         {
67             k-=x;
68             ans|=1<<i;
69             for(int j=ll;j<=rr;j++)
70             {
71                 int y=a[j]&(1<<i);y>>=i;
72                 if(y==0) nl[j]=tr[nl[j]].rc,nr[j]=tr[nr[j]].rc;
73                 else nl[j]=tr[nl[j]].lc,nr[j]=tr[nr[j]].lc;
74             }
75         }
76     }
77     return ans;
78 }
79
80 int main()
81 {
82     int n,m;
83     scanf("%d%d",&n,&m);
84     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
85     for(int j=1;j<=m;j++)
86     {
87         int b;
88         scanf("%d",&b);
89         add(j,b);
90     }
91     int q;
92     scanf("%d",&q);
93     for(int i=1;i<=q;i++)
94     {
95         int ll,rr,l,r,k;
96         scanf("%d%d%d%d%d",&ll,&rr,&l,&r,&k);
97         k=(rr-ll+1)*(r-l+1)-k+1;
98         printf("%d\n",query(ll,rr,l,r,k));
99     }
100     return 0;
101 }


View Code

2017-04-08 14:47:45
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: