BZOJ 3261 最大异或和 && qwb VS 去污棒(可持久化01Trie)
2017-08-29 22:42
513 查看
Problem I: qwb VS 去污棒
Time Limit: 2 Sec Memory Limit: 256 MB
Submit: 95 Solved: 36
[Submit][Status][Web Board]
Description
qwb表白学姐失败后,郁郁寡欢,整天坐在太阳底下赏月。在外人看来,他每天自言自语,其实他在和自己的影子“去污棒”聊天。
去污棒和qwb互相出题考验对方,去污棒问了qwb这样一个问题:
现已知一个有n个正整数的序列a[1],a[2]…a
,接下来有m个操作
操作一共有两种:
1.在序列末尾添加一个数x。
2.查询suf[p] xor x的最大值,其中xor是异或 ,l<=p<=r,
suf[t]表示从t开始的后缀的异或和,即suf[t]=a[t] xor a[t+1] xor …xor a[len],len为序列长度。
Input
第一行一个整数T(<=5),表示一共有T组数据。
每组数据第一行两个整数n(<=200000),m(<=200000),意义如上所述。
随后一行有n个数,表示初始序列。
随后m行,每行表示一个操作。
操作有两种,1: x 表示在末尾添加一个x,2: l r x表示查询suf[p] xor x的最大值,其中l<= p <= r,
所有数及x不超过224 且保证所有操作合法。
Output
每组测试数据的第一行输出”Case x:”,x为数据组数的标号,从1开始。
接下来,对每个操作2输出一行答案。
Sample Input
1
5 5
1 2 3 4 5
2 1 3 4
1 10
1 7
2 4 4 5
2 1 5 19
Sample Output
Case 1:
6
9
31
思路:
长度为n的序列有:prexor
^prexor[k] = sufxor[k+1]
因为是求异或最大 所以想到的是字典树,又因为询问的是区间,所以可以用可持久化字典树
具体思路见:点击打开链接
代码:
Time Limit: 2 Sec Memory Limit: 256 MB
Submit: 95 Solved: 36
[Submit][Status][Web Board]
Description
qwb表白学姐失败后,郁郁寡欢,整天坐在太阳底下赏月。在外人看来,他每天自言自语,其实他在和自己的影子“去污棒”聊天。
去污棒和qwb互相出题考验对方,去污棒问了qwb这样一个问题:
现已知一个有n个正整数的序列a[1],a[2]…a
,接下来有m个操作
操作一共有两种:
1.在序列末尾添加一个数x。
2.查询suf[p] xor x的最大值,其中xor是异或 ,l<=p<=r,
suf[t]表示从t开始的后缀的异或和,即suf[t]=a[t] xor a[t+1] xor …xor a[len],len为序列长度。
Input
第一行一个整数T(<=5),表示一共有T组数据。
每组数据第一行两个整数n(<=200000),m(<=200000),意义如上所述。
随后一行有n个数,表示初始序列。
随后m行,每行表示一个操作。
操作有两种,1: x 表示在末尾添加一个x,2: l r x表示查询suf[p] xor x的最大值,其中l<= p <= r,
所有数及x不超过224 且保证所有操作合法。
Output
每组测试数据的第一行输出”Case x:”,x为数据组数的标号,从1开始。
接下来,对每个操作2输出一行答案。
Sample Input
1
5 5
1 2 3 4 5
2 1 3 4
1 10
1 7
2 4 4 5
2 1 5 19
Sample Output
Case 1:
6
9
31
思路:
长度为n的序列有:prexor
^prexor[k] = sufxor[k+1]
因为是求异或最大 所以想到的是字典树,又因为询问的是区间,所以可以用可持久化字典树
具体思路见:点击打开链接
代码:
#include<bits/stdc++.h> using namespace std; const int maxn = 4e5+5; int trie[maxn*25][2], sz[maxn*25], rt[maxn]; int n, m, cnt, sum; int update(int pre, int i, int x) { int now = ++cnt; if(!i) { trie[now][0] = trie[now][1] = 0; sz[now] = sz[pre]+1; return now; } int bt = ((x>>(i-1))&1); trie[now][1-bt] = trie[pre][1-bt]; trie[now][bt] = update(trie[pre][bt], i-1, x); sz[now] = sz[trie[now][0]]+sz[trie[now][1]]; return now; } int query(int l, int r, int i, int x) { if(!i) return 0; int bt = ((x>>(i-1))&1); if(sz[trie[r][1-bt]]-sz[trie[l][1-bt]]) return (1<<(i-1))+query(trie[l][1-bt], trie[r][1-bt], i-1, x); else return query(trie[l][bt], trie[r][bt], i-1, x); } int main(void) { int _, ca = 1; cin >> _; while(_--) { scanf("%d%d", &n, &m); rt[0] = trie[0][0] = trie[0][1] = sz[0] = sum = 0; rt[0] = update(rt[0], 25, 0); int tmp; for(int i = 1; i <= n; i++) { scanf("%d", &tmp); sum ^= tmp; rt[i] = update(rt[i-1], 25, sum); } printf("Case %d:\n", ca++); while(m--) { int cmd, l, r, x; scanf("%d", &cmd); if(cmd == 1) { scanf("%d", &tmp); sum ^= tmp; n++; rt = update(rt[n-1], 25, sum); } else { scanf("%d%d%d", &l, &r, &x); l--, r--; printf("%d\n", query(rt[l-1], rt[r], 25, sum^x)); } } } return 0; }
相关文章推荐
- bzoj 3261 最大异或和【可持久化trie】
- [BZOJ]3261: 最大异或和 可持久化Trie
- BZOJ 3261 最大异或和 可持久化Trie
- BZOJ_3261_最大异或和_可持久化trie
- BZOJ 3261 最大异或和(可持久化trie)
- bzoj 3261: 最大异或和 可持久化Trie
- [BZOJ3261][最大异或和][可持久化Trie]
- BZOJ 3261: 最大异或和 [可持久化Trie]
- BZOJ 3261 最大异或和 可持久化Trie
- BZOJ 3261: 最大异或和( 可持久化trie )
- [bzoj3261][可持久化Tire]最大异或和
- 3261: 最大异或和 可持久化trie
- 【BZOJ 4103】 [Thu Summer Camp 2015]异或运算 可持久化01Trie
- [可持久化字典树] BZOJ 3261 最大异或和
- bzoj 3261: 最大异或和 可持久化字典树
- [BZOJ 3261]最大异或和:可持久化字典树
- BZOJ 3261 最大异或和 可持久化Trie树
- BZOJ 3261 浅谈可持久化TRIE树最大连续异或和
- 【bzoj3261】【最大异或和】可持久化trie树+贪心
- 【BZOJ】【P3261】【最大异或和】【题解】【可持久化Trie】