1 // 可持久化Trie,例题:BZOJ3261 2 const int N = 600010; 3 int trie[N*24][2], latest[N*24]; // latest和end可合并为一个数组 4 int s[N], root[N], n, m, tot; 5 // 本题需要统计子树latest,故使用递归插入s[i],当前为s[i]的第k位 6 void insert(int i, int k, int p, int q) { 7 if (k < 0) { 8 latest[q] = i; 9 return; 10 } 11 int c = s[i] >> k & 1; 12 if (p) trie[q][c ^ 1] = trie[p][c ^ 1]; 13 trie[q][c] = ++tot; 14 insert(i, k - 1, trie[p][c], trie[q][c]); 15 latest[q] = max(latest[trie[q][0]], latest[trie[q][1]]); 16 } 17 18 int ask(int now, int val, int k, int limit) { 19 if (k < 0) return s[latest[now]] ^ val; 20 int c = val >> k & 1; 21 if (latest[trie[now][c ^ 1]] >= limit) 22 return ask(trie[now][c ^ 1], val, k - 1, limit); 23 else 24 return ask(trie[now][c], val, k - 1, limit); 25 } 26 27 int main() { 28 cin >> n >> m; 29 latest[0] = -1; 30 root[0] = ++tot; 31 insert(0, 23, 0, root[0]); 32 for (int i = 1; i <= n; i++) { 33 int x; scanf("%d", &x); 34 s[i] = s[i - 1] ^ x; 35 root[i] = ++tot; 36 insert(i, 23, root[i - 1], root[i]); 37 } 38 for (int i = 1; i <= m; i++) { 39 char op[2]; scanf("%s", op); 40 if (op[0] == 'A') { 41 int x; scanf("%d", &x); 42 root[++n] = ++tot; 43 s[n] = s[n - 1] ^ x; 44 insert(n, 23, root[n - 1], root[n]); 45 } 46 else { 47 int l, r, x; scanf("%d%d%d", &l, &r, &x); 48 printf("%d ", ask(root[r - 1], x ^ s[n], 23, l - 1)); 49 } 50 } 51 }
可持久化线段树
1 struct smt 2 { 3 int lc,rc; 4 int dat; 5 }t[MLOG_N]; 6 int tot,root[M]; 7 int n,a[N]; 8 9 int build(int l,int r) 10 { 11 int p=++tot; 12 if(l==r){t[p].dat=a[l];return p;} 13 int mid=(l+r)>>1; 14 t[p].lc=build(l,mid); 15 t[p].rc=build(mid+1,r); 16 t[p].dat=max(t[p].lc,t[p].rc); 17 return p; 18 } 19 20 root[0]=build(1,n); 21 22 int modify(int now,int l,int r,int x,int val) 23 { 24 int p=++tot; 25 t[p]=t[now]; 26 if(l==r) {t[p].dat=val;return p;} 27 int mid=(l+r)>>1; 28 if(x<=mid) t[p].lc=modify(t[now].lc,l,mid,x,val); 29 else t[p].rc=modify(t[now].rc,mid+1,r,x,val); 30 t[p].dat=max(t[t[p].lc].dat,t[t[p].rc].dat); 31 return p; 32 } 33 34 root[i]=modify(root[i-1],1,n,x,val); 35 36 int query(int p,int q,int l,int r,int k) 37 { 38 if(l==r) return l; 39 int mid=(l+r)>>1; 40 int lcnt=t[t[p].lc].cnt-t[t[q].lc].cnt; 41 if(k<=lcnt) return query(t[p].lc,t[q].lc,l,mid,k); 42 else return query(t[p].rc,t[q].rc,mid+1,r,k-lcnt); 43 } 44 45 int ans=query(root[R[i]],root[L[i]-1],1,t,K[i]);