• bzoj 3223 文艺平衡树 splay 区间翻转


    bzoj-3223

    splay 区间翻转最简单的应用。

    本来只要[1,n]的区间,建立树的时候要建立[0,n+1]的区间,因为对区间 [l,r] 翻转的时候需要先把 l-1 的节点旋转到根节点的位置, 然后在将 r+1 的节点旋转到 l-1 的 右儿子, 那么 [l, r] 这段区间就在 r + 1 的左子树上了, 我们只需要对左子树打一个翻转标记来减少翻转次数就好了。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define max3(a,b,c) max(a,max(b,c))
     12 #define min3(a,b,c) min(a,min(b,c))
     13 typedef pair<int,int> pll;
     14 const int inf = 0x3f3f3f3f;
     15 const LL INF = 0x3f3f3f3f3f3f3f3f;
     16 const LL mod =  (int)1e9+7;
     17 const int N = 1e5 + 100;
     18 int tot = 0, root;
     19 int n, m;
     20 struct Node{
     21     int son[2], pre;
     22     int val, sz, is_swap;
     23     void init(int x){
     24         val = x;   sz = 1;
     25         is_swap = pre = son[0] = son[1] = 0;
     26     }
     27 }tr[N];
     28 void Push_up(int x){
     29     if(!x) return;
     30     tr[x].sz = tr[tr[x].son[1]].sz + tr[tr[x].son[0]].sz + 1;
     31 }
     32 void Push_down(int x){
     33     if(tr[x].is_swap){
     34         tr[x].is_swap = 0;
     35         int &l = tr[x].son[0], &r = tr[x].son[1];
     36         tr[l].is_swap ^= 1; tr[r].is_swap ^= 1;
     37         swap(l, r);
     38     }
     39 }
     40 int build(int ll, int rr){
     41     if(ll > rr) return 0;
     42     int x = ++tot;
     43     int m = ll + rr >> 1;
     44     int &l = tr[x].son[0], &r = tr[x].son[1];
     45     tr[x].init(m);
     46     l = build(ll, m-1);
     47     r = build(m+1, rr);
     48     tr[l].pre = tr[r].pre = x;
     49     Push_up(x);
     50     return x;
     51 }
     52 void rotate(int x){
     53     int y = tr[x].pre;
     54     int z = tr[y].pre;
     55     int k = x == tr[y].son[1];
     56     tr[x].pre = z;
     57     tr[z].son[y == tr[z].son[1]] = x;
     58     tr[y].son[k] = tr[x].son[k^1];
     59     tr[tr[y].son[k]].pre = y;
     60     tr[x].son[k^1] = y;
     61     tr[y].pre = x;
     62     Push_up(y);
     63 }
     64 void splay(int x, int goal){
     65     Push_down(x);
     66     while(tr[x].pre != goal){
     67         int y = tr[x].pre;
     68         int z = tr[y].pre;
     69         if(z != goal){
     70             if((tr[y].son[0] == x) ^ (tr[z].son[0] == y))   rotate(x); ///x和y分别是y和z的同一段的儿子
     71             else rotate(y);
     72         }
     73         rotate(x);
     74     }
     75     if(!goal) root = x;
     76     Push_up(x);
     77 }
     78 void dfs(int x){
     79     Push_down(x);
     80     if(tr[x].son[0]) dfs(tr[x].son[0]);
     81     if(tr[x].val <= n && tr[x].val >= 1)
     82        printf("%d ", tr[x].val);
     83     if(tr[x].son[1]) dfs(tr[x].son[1]);
     84 }
     85 int Find(int x, int p){
     86     Push_down(p);
     87     int &l = tr[p].son[0], &r = tr[p].son[1];
     88     if(x == tr[l].sz + 1) return p;
     89     if(x <= tr[l].sz) return Find(x, l);
     90     return Find(x- tr[l].sz - 1, r);
     91 }
     92 int main(){
     93     int l, r, pl, pr;
     94     scanf("%d%d", &n, &m);
     95     root = build(0, n+2);
     96     while(m--){
     97         scanf("%d%d", &l, &r);
     98         pl = Find(l, root);
     99         pr = Find(r+2, root);
    100         splay(pl, 0);
    101         splay(pr, root);
    102         tr[tr[pr].son[0]].is_swap ^= 1;
    103     }
    104     dfs(root);
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    OpenCV 写入视频流
    Flyweight 模式
    Builder 模式
    MySQL插入数据
    MySQL新建表
    2's Power
    DeepID人脸识别算法之三代(转)
    FaceNet--Google的人脸识别(转)
    DeepFace--Facebook的人脸识别(转)
    leetcode6 Reverse Words in a String 单词取反
  • 原文地址:https://www.cnblogs.com/MingSD/p/9388808.html
Copyright © 2020-2023  润新知