可持久化数据结构

 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\n", 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]);

 

posted @ 2019-04-05 20:21  universeplayer  阅读(177)  评论(0编辑  收藏  举报