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 }

原文地址:https://www.cnblogs.com/lnxcj/p/10029811.html

时间: 2024-11-07 23:49:48

bzoj4103[Thu Summer Camp 2015]异或运算(可持久化trie树)的相关文章

【BZOJ4103】[Thu Summer Camp 2015]异或运算 可持久化Trie树

[BZOJ4103][Thu Summer Camp 2015]异或运算 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行,每行

bzoj4103 [Thu Summer Camp 2015]异或运算(可持久化trie)

内存限制:512 MiB 时间限制:1000 ms 题目描述 给定长度为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. 输入格式 第一行包含两个正整数n,m,分别表示两个数列的长度 第二行包含n个非负整数xi 第三行包含m个非负整数yj 第四行包含一个正整数p,表示询问次数 随后p行,每行均包含5个正整数,用来描述一次询问,每行

[BZOJ4103][Thu Summer Camp 2015]异或运算

试题描述 给定长度为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. 输入 第一行包含两个正整数n,m,分别表示两个数列的长度 第二行包含n个非负整数xi 第三行包含m个非负整数yj 第四行包含一个正整数p,表示询问次数 随后p行,每行均包含5个正整数,用来描述一次询问,每行包含五个正整数u,d,l,r,k,含义如题意所述. 输

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

4103: [Thu Summer Camp 2015]异或运算 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 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,分别表示两

bzoj4103异或运算 可持久化trie树

要去清华冬令营了,没找到2016年的题,就先坐一坐15年的. 因为n很小,就按照b串建可持久化trie树,a串暴力枚举. 其他的直接看代码. #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; inline int read() { int x=0,f=1,ch=getchar(); while(ch<'0'||ch

【bzoj3281】最大异或和 可持久化Trie树

题目描述 给定一个非负整数序列 {a},初始长度为 N.       有M个操作,有以下两种操作类型:1.A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1.2.Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得:a[p] xor a[p+1] xor ... xor a[N] xor x 最大,输出最大是多少. 输入 第一行包含两个整数 N  ,M,含义如问题描述所示.   第二行包含 N个非负整数,表示初始的序列 A . 接下来 M行,每行描述一个

[bzoj3261]最大异或和[可持久化trie树]

因为要求异或和最大,所以可以考虑从高位开始,向低位枚举尽可能接近~x的值,所以以二进制位为关键字,建立可持久化trie树,根据异或和的性质,XOR_SUM{i,j}=XOR_SUM{1,j} xor XOR_SUM{1,i-1},所以查询问题也可以解决了. 1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <c

【BZOJ 4104】【Thu Summer Camp 2015】解密运算

http://www.lydsy.com/JudgeOnline/problem.php?id=4104 网上题解满天飞,我也懒得写了 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 200003; int in() { int k = 0, fh = 1; char c = getchar(); for(; c < '0' || c

BZOJ 3261 最大异或和 可持久化Trie树

题目大意:给定一个序列,提供下列操作: 1.在数组结尾插入一个数 2.给定l,r,x,求一个l<=p<=r,使x^a[p]^a[p+1]^...^a[n]最大 首先我们可以维护前缀和 然后就是使x^sum[n]^sum[p-1]最大 x^sum[n]为定值,于是用Trie树贪心即可 考虑到l-1<=p-1<=r-1,我们不能对于每个询问都建一棵Trie树,但是我们可以对于Trie数维护前缀和,建立可持久化Trie树 每个区间[l,r]的Trie树为tree[r]-tree[l-1]