4546: codechef XRQRS
可持久化Trie
codechef上過了,bzoj上蜜汁re,看別人說要開5.2e5才行。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 5.2e5+5;
inline int read() {
char c=getchar(); int x=0,f=1;
while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
void put(int x) {
for(int i=19; i>=0; i--) {
if(x & (1<<i)) putchar('1');
else putchar('0');
}
printf(" %d\n", x);
}
int Q, op, l, r;
int tot;
namespace trie {
#define ch(x, f) t[x].ch[f]
struct node {int ch[2], size;} t[N * 20];
int sz, root[N];
void insert(int &x, int p, int val) { //printf("insert %d %d\n", val, bool(val & (1<<p)));
t[++sz] = t[x]; x = sz;
t[x].size ++;
if(p < 0) return;
if(val & (1<<p)) insert(t[x].ch[1], p-1, val);
else insert(t[x].ch[0], p-1, val);
}
int max_xor(int x, int y, int p, int val) {
int ans = 0;
while(p >= 0) {
bool f = ~ val & (1<<p);
if(t[ch(y, f)].size - t[ch(x, f)].size == 0) f ^= 1;
x = t[x].ch[f], y = t[y].ch[f];
if(f) ans |= (1<<p);
p--;
}
return ans;
}
int small(int x, int y, int p, int val) {
int ans = 0;
while(p >= 0) {
bool f = val & (1<<p);
if(f) ans += t[ch(y, 0)].size - t[ch(x, 0)].size;
y = ch(y, f), x = ch(x, f);
p--;
}
ans += t[y].size - t[x].size;
return ans;
}
int kth(int x, int y, int p, int k) {
int ans = 0, lsize = 0;
while(p >= 0) {
int _ = lsize + t[ch(y, 0)].size - t[ch(x, 0)].size;
if(k <= _) y = ch(y, 0), x = ch(x, 0);
else lsize = _, ans |= (1<<p), y = ch(y, 1), x = ch(x, 1);
p--;
}
return ans;
}
} using trie::root;
void add(int x) {
tot++;
root[tot] = root[tot-1];
trie::insert(root[tot], 19, x);
}
void del(int k) {tot -= k;}
void max_xor(int l, int r, int x) { //printf("max_xor %d %d %d\n", l, r, x);
int ans = trie::max_xor(root[l-1], root[r], 19, x);
printf("%d\n", ans);
}
void smaller(int l, int r, int x) {
int ans = trie::small(root[l-1], root[r], 19, x);
printf("%d\n", ans);
}
void kth(int l, int r, int k) { //printf("kth %d %d %d\n", l, r, k);
int ans = trie::kth(root[l-1], root[r], 19, k);
printf("%d\n", ans);
}
int main() {
freopen("in", "r", stdin);
Q = read();
for(int i=1; i<=Q; i++) {
op = read() - 1; //printf("\n-------------------- %d %d\n", i, op);
if(op == 0) add(read());
else if(op == 2) del(read());
else {
l = read(); r = read();
if(op == 1) max_xor(l, r, read());
else if(op == 3) smaller(l, r, read());
else kth(l, r, read());
}
}
}