• 可持久化数据结构


     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]);
  • 相关阅读:
    如何提交docker镜像到DockerHub
    【leetcode】200. Number of Islands
    【Java NIO】一文了解NIO
    【Java】同步阻塞式(BIO)TCP通信
    【剑指offer】9、斐波拉契数列
    SolidWorks242个使用技巧
    BR(BoomerangRobot)机器人项目
    Android学习笔记基于回调的事件处理
    Android学习笔记基于监听的事件处理
    Android学习笔记Log类输出日志信息
  • 原文地址:https://www.cnblogs.com/universeplayer/p/10659764.html
Copyright © 2020-2023  润新知