zoukankan      html  css  js  c++  java
  • 平衡树专题

    复习一波平衡树!

    3224: Tyvj 1728 普通平衡树

    链接

    怎么能少得了这道题呢。

      1 #include<cstdio>
      2 #include<cctype>
      3 
      4 const int N = 1000100;
      5 
      6 int siz[N],ch[N][2],fa[N],cnt[N],data[N];
      7 int Root,tn;
      8 
      9 #define ls ch[p][0]
     10 #define rs ch[p][1]
     11 
     12 int son(int x) {
     13     return x==ch[fa[x]][1];
     14 }
     15 void pushup(int p) {
     16     siz[p] = siz[ls] + siz[rs] + cnt[p];
     17 }
     18 void rotate(int x) {
     19     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
     20     if (z) ch[z][c] = x;else Root = x;fa[x] = z;
     21     ch[x][!b] = y;fa[y] = x;
     22     ch[y][b] = a;if (a) fa[a] = y;
     23     pushup(y),pushup(x);
     24 }
     25 void splay(int x,int rt) {
     26     while (fa[x] != rt) {
     27         int y = fa[x],z = fa[y];
     28         if (z==rt) rotate(x);
     29         else {
     30             if (son(x)==son(y)) rotate(y),rotate(x);
     31             else rotate(x),rotate(x); 
     32         }
     33     }
     34 }
     35 int getrnk(int x) {
     36     int p = Root,ans = 0;
     37     while (true) {
     38         if (!p) return ans + 1;
     39         if (x == data[p]) {ans += siz[ls];splay(p,0);return ans+1;}
     40         if (x < data[p]) p = ls;
     41         else { 
     42             ans += siz[ls] + cnt[p];
     43             p = rs;
     44         }
     45     }
     46 }
     47 int getkth(int k) {
     48     int p = Root;
     49     while (true) {
     50         if (siz[ls] < k && k <= siz[ls] + cnt[p]) return data[p];
     51         if (k <= siz[ls]) p = ls;
     52         else {
     53             k -= siz[ls] + cnt[p]; 
     54             p = rs; 
     55         }
     56     }
     57 }
     58 int Newnode(int pa,int d) {
     59     ++tn;siz[tn] = cnt[tn] = 1;ch[tn][1] = ch[tn][0] = 0;
     60     data[tn] = d;fa[tn] = pa;
     61     return tn;
     62 }
     63 void Insert(int x) {
     64     if (!Root) {Root = Newnode(0,x);return ;}
     65     int p = Root,pa = 0;
     66     while (true) {
     67         if (data[p]==x) {
     68             cnt[p] ++;pushup(p);pushup(pa);splay(p,0);return ; // Splay ????????????????? 
     69         }
     70         pa = p; // ??! 
     71         p = ch[p][x > data[p]];
     72         if (!p) {
     73             p = Newnode(pa,x);
     74             ch[pa][x > data[pa]] = p;
     75             pushup(p),pushup(pa);splay(p,0);
     76             break; 
     77         }
     78     }
     79 }
     80 void Clear(int p) {
     81     siz[p] = cnt[p] = ch[p][0] = ch[p][1] = fa[p] = data[p] = 0;
     82 }
     83 void Delete(int x) {
     84     getrnk(x);
     85     int &p = Root,tmp;
     86     if (cnt[p]) {cnt[p]--;pushup(p);return ;}
     87     if (!ls && !rs) {Clear(p);Root = 0;return ;}
     88     if (!ls || !rs) {tmp = p;p = ls?ls:rs;fa[p] = 0;Clear(tmp);return ;}
     89     int pre = ls;
     90     while (ch[pre][1]) pre = ch[pre][1];
     91     tmp = p;p = pre;
     92     splay(p,0);
     93     ch[p][1] = ch[tmp][1];fa[ch[tmp][1]] =  p;
     94     Clear(tmp);pushup(p);
     95 }
     96 int main() {
     97     int T,opt,x;
     98     scanf("%d",&T);
     99     while (T--) {
    100         scanf("%d%d",&opt,&x);
    101         if (opt==1) Insert(x);
    102         else if (opt==2) Delete(x);
    103         else if (opt==3) printf("%d
    ",getrnk(x));
    104         else if (opt==4) printf("%d
    ",getkth(x));
    105         else if (opt==5) printf("%d
    ",getkth(getrnk(x)-1)); 
    106         else printf("%d
    ",getkth(getrnk(x+1)));
    107     } 
    108 }
    View Code

    2827: 千山鸟飞绝 

    链接

    splay插入删除,下放标记,注意下放的位置。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<cmath>
      6 #include<cctype>
      7 #include<set>
      8 #include<queue>
      9 #include<vector>
     10 #include<map>
     11 #include<stack>
     12 #define pa pair<int,int>
     13 #define lc ch[p][0]
     14 #define rc ch[p][1]
     15 using namespace std;
     16 typedef long long LL;
     17 
     18 inline int read() {
     19     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     20     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     21 }
     22 
     23 const int N = 300005;
     24 const LL M = 1ll << 31;
     25 struct Bird{
     26     int tuan, shi, wei, id;
     27     Bird() {}
     28     Bird(int a,int b,int c,int d) { tuan = a, shi = b, wei = c, id = d; }
     29 }T[N], A[N], Now;
     30 struct OPT{
     31     int id, x, y;
     32 }opt[N];
     33 int ch[N][2], fa[N], siz[N], mx[N], Root[N << 1], Tuan[N], Shi[N], bel[N], st[N];
     34 int Index, RootIndex, NowPos;
     35 LL ans[N];
     36 stack<int> sk;
     37 map< pa ,int>Rt;
     38 
     39 inline int son(int x) { return ch[fa[x]][1] == x; }
     40 inline void pushup(int p) {
     41     siz[p] = siz[lc] + siz[rc] + 1;
     42     mx[p] = max(T[p].wei, max(mx[lc], mx[rc]));
     43 }
     44 inline void pushdown(int p) {
     45     T[p].tuan = max(T[p].tuan, Tuan[p]), T[p].shi = max(T[p].shi, Shi[p]);
     46     if (Tuan[p]) {
     47         if (lc) Tuan[lc] = max(Tuan[lc], Tuan[p]); 
     48         if (rc) Tuan[rc] = max(Tuan[rc], Tuan[p]);
     49     }
     50     if (Shi[p]) {
     51         if (lc) Shi[lc] = max(Shi[lc], Shi[p]);
     52         if (rc) Shi[rc] = max(Shi[rc], Shi[p]);
     53     }
     54     Tuan[p] = 0, Shi[p] = 0;
     55 }
     56 inline void rotate(int x) {
     57     int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
     58     if (!z) Root[NowPos] = x; else ch[z][c] = x; fa[x] = z;
     59     ch[x][!b] = y; fa[y] = x;
     60     ch[y][b] = a; if (a) fa[a] = y;
     61     pushup(y); pushup(x);
     62 }
     63 inline void Splay(int x,int rt) {
     64     int top = 0, p = x;
     65     while (p) st[++top] = p, p = fa[p];
     66     while (top) pushdown(st[top]), top --;
     67     while (fa[x] != rt) {
     68         int y = fa[x], z = fa[y];
     69         if (z == rt) rotate(x);
     70         else {
     71             if (son(x) == son(y)) rotate(y), rotate(x);
     72             else rotate(x), rotate(x);
     73         }
     74     }
     75 }
     76 void getpos(int p,int k) {
     77     while (true) {
     78         if (k == T[p].id) { Splay(p, 0); Now = T[p]; return ;} // Now找到的需要删除的点,保存下来,再插入到另一棵splay中,注意要先下放完标记!!! 
     79         if (k < T[p].id) p = lc;
     80         else p = rc; 
     81     }
     82 }
     83 inline int NewNode(int f,const Bird &A) {
     84     int p = sk.size() ? sk.top() : ++Index;
     85     T[p] = A, fa[p] = f; ch[p][0] = ch[p][1] = 0; siz[p] = 1, mx[p] = A.wei;    
     86     return p;
     87 }
     88 void Insert(int &Root,Bird A) {
     89     if (!Root) { Root = NewNode(0, A); return ; }
     90     int p = Root, pre = 0;
     91     while (true) {
     92         pushdown(p);
     93         pre = p; p = ch[p][A.id > T[p].id];
     94         if (!p) {
     95             p = NewNode(pre, A); // 此处应有下方标记!!!
     96             ch[pre][A.id > T[pre].id] = p;
     97             pushup(p); pushup(pre); 
     98             Splay(p, 0); break;
     99         }
    100     }
    101 }
    102 inline void Clear(int p) {
    103     siz[p] = ch[p][0] = ch[0][1] = fa[p] = mx[p] = Tuan[p] = Shi[p] = 0; sk.push(p);
    104 }
    105 void Delete(int &Root,int k) { // 在以Root为根的splay中删除标号为k的点 
    106     getpos(Root, k);
    107     int &p = Root, tmp;
    108     if (!lc && !rc) { Clear(p); p = 0; return ; }
    109     if (!lc || !rc) { tmp = p; p = lc ? lc : rc; fa[p] = 0; Clear(tmp); return ; }
    110     int pre = lc; while (ch[pre][1]) pre = ch[pre][1];
    111     tmp = p; p = pre;
    112     Splay(p, 0);
    113     ch[p][1] = ch[tmp][1], fa[ch[tmp][1]] = p;
    114     Clear(tmp); pushup(p);
    115 }
    116 void dfs(int p) {
    117     pushdown(p);
    118     ans[T[p].id] = 1ll * T[p].tuan * T[p].shi;
    119     if (lc) dfs(lc); 
    120     if (rc) dfs(rc);
    121 }
    122 void de(int x) {
    123     cout << x << " : 
    ";
    124     cout << "pos : " << bel[x] << "
    ";
    125     cout << "siz : " << siz[Root[bel[x]]] << "
    ";
    126     dfs(Root[bel[x]]);
    127     cout << "birds : 
    ";
    128     for (int i = 1; i <= 20; ++i) 
    129         if (bel[T[i].id] == bel[x]) 
    130             cout << T[i].id << " " << T[i].wei << " " << T[i].shi << " " << T[i].tuan << "
    ";
    131     puts("--------");
    132 }
    133 int main() { 
    134     int n = read();
    135     for (int i = 1; i <= n; ++i) {
    136         int w = read(), x = read(), y = read(), tmp = Rt[pa(x, y)], R;
    137         if (!tmp) tmp = ++RootIndex, Rt[pa(x, y)] = tmp;
    138         A[i] = Bird(0, 0, w, i);
    139         
    140         NowPos = tmp; R = Root[tmp];
    141         if (R) {
    142             Shi[R] = max(Shi[R], A[i].wei), Tuan[R] = max(Tuan[R], siz[R]);
    143             A[i].shi = max(A[i].shi, mx[R]), A[i].tuan = max(A[i].tuan, siz[R]);
    144         }
    145         
    146         Insert(Root[tmp], A[i]); 
    147         bel[i] = tmp;
    148     }
    149     int Q = read();
    150     while (Q--) {
    151         int v = read(), x = read(), y = read(), tmp = Rt[pa(x, y)], R;
    152         if (!tmp) tmp = ++RootIndex, Rt[pa(x, y)] = tmp; // tmp这个位置离散后的标号 
    153         NowPos = bel[v]; Delete(Root[bel[v]], v); // Root
    154         
    155         NowPos = tmp; R = Root[tmp];
    156         if (R) {
    157             Shi[R] = max(Shi[R], Now.wei), Tuan[R] = max(Tuan[R], siz[R]);
    158             Now.shi = max(Now.shi, mx[R]), Now.tuan = max(Now.tuan, siz[R]);
    159         }
    160         
    161         Insert(Root[tmp], Now); 
    162         bel[v] = tmp; 
    163 //        de(v);
    164     }
    165     for (int i = 1; i <= n; ++i) 
    166         if (Root[bel[i]]) dfs(Root[bel[i]]), Root[bel[i]] = 0;
    167     for (int i = 1; i <= n; ++i) printf("%lld
    ", ans[i]);
    168     return 0;
    169 }
    View Code

    1058: [ZJOI2007]报表统计

    链接

    前驱后继。set。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<cctype>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #include<map>
    11 using namespace std;
    12 typedef long long LL;
    13 
    14 inline int read() {
    15     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    16     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    17 }
    18 
    19 const int N = 500005;
    20 multiset<int> s;
    21 set<int> t;
    22 int st[N], ed[N], Min = 2e9;
    23 
    24 void insT(int x) {
    25     set<int> :: iterator it = t.lower_bound(x);
    26     int t1 = (*it) - x, t2 = x - *(--it);
    27     Min = min(Min, min(t1, t2));
    28     t.insert(x);
    29 }
    30 
    31 int main() {
    32     int n = read(), m = read();
    33     t.insert(-1e9), t.insert(1e9);
    34     for (int i = 1; i <= n; ++i) {
    35         int x = read();
    36         st[i] = ed[i] = x;
    37         insT(x);
    38         if (i >= 2) s.insert(abs(st[i] - ed[i - 1]));
    39     }
    40     char opt[20];
    41     while (m --) {
    42         scanf("%s", opt);
    43         if (opt[0] == 'I') {
    44             int p = read(), x = read();
    45             if (p != n) {    
    46                 s.erase(s.find(abs(st[p + 1] - ed[p])));
    47                 s.insert(abs(st[p + 1] - x));
    48             }
    49             s.insert(abs(x - ed[p]));
    50             ed[p] = x; 
    51             insT(x);
    52         }
    53         else if (opt[4] == 'S') printf("%d
    ", Min);
    54         else printf("%d
    ", *s.begin());
    55     }
    56     return 0;
    57 }
    View Code

    1251: 序列终结者

    链接

    维护最大值,区间翻转,被下放标记搞晕了。。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<cmath>
      6 #include<cctype>
      7 #include<set>
      8 #include<queue>
      9 #include<vector>
     10 #include<map>
     11 #define lc ch[p][0]
     12 #define rc ch[p][1]
     13 using namespace std;
     14 typedef long long LL;
     15 
     16 inline int read() {
     17     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     18     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     19 }
     20 
     21 const int N = 50005;
     22 int rev[N], ch[N][2], fa[N], siz[N], st[N], Root;
     23 LL T[N], mx[N], tag[N];
     24 
     25 inline int son(int x) { return ch[fa[x]][1] == x; }
     26 inline void pushup(int p) {
     27     siz[p] = siz[lc] + siz[rc] + 1;
     28     mx[p] = max(T[p], max(mx[lc], mx[rc]));
     29 }
     30 inline void pushdown(int p) {
     31     if (rev[p]) swap(lc, rc), rev[lc] ^= 1, rev[rc] ^= 1, rev[p] ^= 1;
     32     if (tag[p]) { 
     33         T[p] += tag[p];
     34         mx[lc] += tag[p], mx[rc] += tag[p];
     35         tag[lc] += tag[p], tag[rc] += tag[p];
     36         tag[p] = 0; 
     37     }
     38 }
     39 inline void rotate(int x) {
     40     int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
     41     if (!z) Root = x; else ch[z][c] = x; fa[x] = z;
     42     ch[x][!b] = y; fa[y] = x;
     43     ch[y][b] = a; if (a) fa[a] = y;
     44     pushup(y); pushup(x);
     45 }
     46 inline void splay(int x,int rt) {
     47     while (fa[x] != rt) {
     48         int y = fa[x], z = fa[y];
     49         if (z == rt) rotate(x);
     50         else {
     51             if (son(x) == son(y)) rotate(y), rotate(x);
     52             else rotate(x), rotate(x);
     53         }
     54     }
     55 }
     56 int build(int l,int r) {
     57     if (l > r) return 0;
     58     int mid = (l + r) >> 1, tmp;
     59     tmp = build(l, mid - 1);
     60     if (tmp) fa[tmp] = mid, ch[mid][0] = tmp;
     61     tmp = build(mid + 1, r);
     62     if (tmp) fa[tmp] = mid, ch[mid][1] = tmp;
     63     pushup(mid);
     64     return mid;
     65 }
     66 int getkth(int k) {
     67     int p = Root;
     68     while (true) {
     69         pushdown(p);
     70         if (k == siz[lc] + 1) return p;
     71         if (k <= siz[lc]) p = lc;
     72         else k -= siz[lc] + 1, p = rc;
     73     }
     74 }
     75 void Add(int l,int r,LL x) {
     76     l --, r ++;
     77     l = getkth(l), r = getkth(r);
     78     splay(l, 0); splay(r, l);
     79     tag[ch[ch[Root][1]][0]] += x;
     80     mx[ch[ch[Root][1]][0]] += x;
     81 }
     82 void Reverse(int l,int r) {
     83     l --, r ++;
     84     l = getkth(l), r = getkth(r);
     85     splay(l, 0); splay(r, l);
     86     rev[ch[ch[Root][1]][0]] ^= 1;
     87 }
     88 LL query(int l,int r) {
     89     l --, r ++;
     90     l = getkth(l), r = getkth(r);
     91     splay(l, 0); splay(r, l);
     92     return mx[ch[ch[Root][1]][0]];
     93 }
     94 int main() {
     95     int n = read(), m = read();
     96     T[1] = -1e18, T[n + 2] = -1e18; mx[0] = -1e18;
     97     Root = build(1, n + 2);
     98     while (m --) {
     99         int opt = read(), l = read() + 1, r = read() + 1;
    100         if (opt == 1) Add(l, r, read());
    101         else if (opt == 2) Reverse(l, r);
    102         else printf("%lld
    ", query(l, r));
    103     }
    104     return 0;
    105 }
    View Code

    1014: [JSOI2008]火星人prefix

    链接

    求lcp,可以后缀数组+st表,但是这里有修改,所以直接二分+hash,加上平衡树维护hash值。

    因为两个错误调了好久!!!

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<cmath>
      6 #include<cctype>
      7 #include<set>
      8 #include<queue>
      9 #include<vector>
     10 #include<map>
     11 #define lc ch[p][0]
     12 #define rc ch[p][1]
     13 using namespace std;
     14 typedef long long LL;
     15 typedef unsigned long long uLL;
     16 
     17 inline int read() {
     18     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     19     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     20 }
     21 
     22 const int N = 100005;
     23 const uLL B = 31;
     24 int ch[N][2], siz[N], fa[N], Index, Root, n;
     25 uLL ha[N], mi[N], T[N];
     26 char s[N];
     27 
     28 inline int son(int x) { return ch[fa[x]][1] == x; }
     29 inline void pushup(int p) {
     30     siz[p] = siz[lc] + siz[rc] + 1;
     31     ha[p] = ha[lc] * mi[siz[rc] + 1] + T[p] * mi[siz[rc]] + ha[rc];
     32 }
     33 inline void rotate(int x) {
     34     int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
     35     if (z) ch[z][c] = x; else Root = x; fa[x] = z;
     36     ch[x][!b] = y; fa[y] = x;
     37     ch[y][b] = a; if (a) fa[a] = y;
     38     pushup(y); pushup(x);
     39 }
     40 inline void splay(int x,int rt) {
     41     while (fa[x] != rt) {
     42         int y = fa[x], z = fa[y];
     43         if (z == rt) rotate(x);
     44         else {
     45             if (son(x) == son(y)) rotate(y), rotate(x);
     46             else rotate(x), rotate(x);
     47         }
     48     }
     49 }
     50 int build(int l,int r) {
     51     if (l > r) return 0;
     52     int mid = (l + r) >> 1, tmp;
     53     tmp = build(l, mid - 1);
     54     if (tmp) fa[tmp] = mid, ch[mid][0] = tmp;
     55     tmp = build(mid + 1, r);
     56     if (tmp) fa[tmp] = mid, ch[mid][1] = tmp;
     57     pushup(mid);
     58     return mid;
     59 }
     60 inline int getpos(int k) {
     61     int p = Root;
     62     while (true) {
     63         if (k == siz[lc] + 1) return p;
     64         if (k <= siz[lc]) p = lc;
     65         else k -= siz[lc] + 1, p = rc;
     66     }
     67 }
     68 uLL getha(int l,int r) {
     69     l --, r ++;
     70     l = getpos(l), r = getpos(r);
     71     splay(l, 0); splay(r, l);
     72     return ha[ch[ch[Root][1]][0]];
     73 }
     74 inline void Insert(int p,int x) {
     75     int l = p, r = p + 1;
     76     l = getpos(l), r = getpos(r);
     77     splay(l, 0); splay(r, l);
     78     int t = ch[Root][1];
     79     ch[t][0] = ++Index, fa[Index] = t, siz[Index] = 1, T[Index] = x, ha[Index] = x;
     80     pushup(t); pushup(Root);
     81 }
     82 inline void Change(int p,int x) {
     83     p = getpos(p); 
     84     splay(p, 0); 
     85     T[Root] = x; 
     86     pushup(Root);
     87 }
     88 inline int query(int a,int b) {
     89     if (a > b) swap(a, b); // !!!!!!!!!!!a不一定小于b!!!!!!!!!!!!!! 
     90     int l = 1, r = Index - b, res = 0; // r的最大值是Index-b!!!not n+2-b 
     91     while (l <= r) {
     92         int mid = (l + r) >> 1;
     93         if (getha(a, a + mid - 1) == getha(b, b + mid - 1)) res = mid, l = mid + 1;
     94         else r = mid - 1;
     95     }
     96     return res;
     97 }
     98 void dfs(int p) {
     99     if (lc) dfs(lc);
    100     printf("%c",(int)T[p] + 'a' - 1);
    101     if (rc) dfs(rc);
    102 }
    103 int main() { 
    104     scanf("%s", s + 1);
    105     
    106     n = strlen(s + 1);
    107     for (int i = 1; i <= n; ++i) T[i + 1] = s[i] - 'a' + 1;
    108     Index = n + 2; mi[0] = 1; 
    109     for (int i = 1; i <= 100001; ++i) mi[i] = mi[i - 1] * B;
    110     Root = build(1, n + 2);
    111     
    112     int m = read(); char opt[10], ch[10];
    113     while (m --) {
    114         scanf("%s", opt);
    115         if (opt[0] == 'Q') {
    116             int l = read() + 1, r = read() + 1;
    117             printf("%d
    ", query(l, r));
    118         } else if (opt[0] == 'R') {
    119             int p = read() + 1; scanf("%s", ch);
    120             Change(p, ch[0] - 'a' + 1);
    121         } else {
    122             int p = read() + 1; scanf("%s", ch);
    123             Insert(p, ch[0] - 'a' + 1);
    124         }
    125     }
    126     return 0;
    127 }
    View Code
  • 相关阅读:
    高效程序猿的45个习惯:敏捷开发修炼之道之主题建议翻译1-10
    VS2010旗舰版安装图解
    ibatis 使用 in 查询的几种XML写法
    人脸识别算法初次了解
    键盘过滤驱动
    python property属性
    癞子麻将胡牌算法实现
    恩布900手机客服,安卓版本号Entboost Android 1.0 正式公布
    C语言递归实现二叉树的先序、中序、后序遍历
    CSS:CSS 属性 选择器
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10112056.html
Copyright © 2011-2022 走看看