zoukankan      html  css  js  c++  java
  • Splay

    Splay的区间维护还是很机智的,不好写是真的。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cmath>
      6 #define REP(i, s, n) for(int i = s; i <= n; i ++)
      7 #define RAP(i, n, s) for(int i = n; i >= s; i --)
      8 using namespace std;
      9 const int maxn = 100000 + 10;
     10 char S[maxn]; int Q;
     11 inline void read(int &x){
     12     x = 0; int sig = 1; char ch = getchar();
     13     while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); }
     14     while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar();
     15     x *= sig; return ;
     16 }
     17 inline void write(int x){
     18     if(x < 0) putchar('-'), x = -x;
     19     int len = 0, buf[20];
     20     while(x) buf[++ len] = x % 10, x /= 10;
     21     RAP(i, len, 0) putchar(buf[i] + '0'); return ;
     22 }
     23 struct Node{
     24     int s, flip; char c;
     25     Node* ch[2];
     26     int cmp(int k){
     27         return k == ch[0] -> s + 1 ? -1 : k > ch[0] -> s;
     28     }
     29     void maintain(){
     30         s = ch[0] -> s + ch[1] -> s + 1; return ;
     31     }
     32     void pushdown(){
     33         if(flip) ch[0] -> flip ^= 1, ch[1] -> flip ^= 1, swap(ch[0], ch[1]), flip = 0; return ;
     34     }
     35 }* null = new Node(), nodes[maxn], * root, * _o, * _left, * _right, * _mid;
     36 int ms = 0;
     37 void rotate(Node* &o, int d){
     38     Node* k = o -> ch[d ^ 1]; o -> ch[d ^ 1] = k -> ch[d]; k -> ch[d] = o;
     39     o -> maintain(); k -> maintain(); o = k; return ; 
     40 }
     41 void splay(Node* &o, int k1){
     42     o -> pushdown(); int d1 = o -> cmp(k1);
     43     if(d1) k1 -= o -> ch[0] -> s + 1; if(d1 == -1) return ;
     44     Node* p = o -> ch[d1]; p -> pushdown();
     45     int d2 = p -> cmp(k1), k2 = d2 ? k1 - p -> ch[0] -> s - 1 : k1;
     46     if(d2 != -1){
     47         splay(p -> ch[d2], k2);
     48         if(d1 == d2) rotate(o, d1 ^ 1); else rotate(o -> ch[d1], d1);
     49     }
     50     rotate(o, d1 ^ 1); return ;
     51 }
     52 void print(Node* &o){
     53     if(o == null) return ;
     54     o -> pushdown();
     55     print(o -> ch[0]);
     56     putchar(o -> c);
     57     print(o -> ch[1]);
     58     return ;
     59 }
     60 void build(Node* &o, int L, int R){
     61     o = null; if(L > R) return ;
     62     int M = L + R >> 1; o = &nodes[ms ++];
     63     o -> c = S[M]; o -> flip = 0;
     64     build(o -> ch[0], L, M - 1); build(o -> ch[1], M + 1, R); //不包含M的两块
     65     o -> maintain(); return ; 
     66 }
     67 void merge(Node* &left, Node* &right){
     68     if(left == null) left = right;
     69     else splay(left, left -> s), left -> ch[1] = right, left -> maintain();//截掉右子树粘过去,别忘了重新维护一下 
     70     return ;
     71 }
     72 void split(Node* &o, Node* &left, Node* &right, int k){//前k小扔到left里 
     73     if(k <= 0) left = null, right = o;//直接搞好了o(* ̄3 ̄)o 
     74     else splay(o, k), left = o, right = left -> ch[1], left -> ch[1] = null, left -> maintain();//砍掉左子树的右孩子贴到右边去,别忘了维护值 
     75     return ;
     76 }
     77 void init(){
     78     scanf("%s", S); read(Q);
     79     build(root, 0, strlen(S) - 1);
     80     return ;
     81 }
     82 void work(){
     83     int L, R;
     84     while(Q --){
     85         read(L); read(R);
     86         split(root, _left, _o, L - 1); split(_o, _mid, _right, R - L + 1);//先拆root再拆 o (⊙ ▽ ⊙)
     87         _mid -> flip ^= 1;
     88         merge(_left, _mid); merge(_left, _right); root = _left;//哦哦一点点合并,merge又不是三元的 (⊙ ▽ ⊙),别忘了root要更新回来 
     89     }
     90     return ;
     91 }
     92 void print(){
     93     print(root);
     94     return ;
     95 }
     96 int main(){
     97     init();
     98     work();
     99     print();
    100     return 0;
    101 }
  • 相关阅读:
    【Selenium IDE】下载安装Chrome和Firefox插件IDE ide了解就行 不是重点 重点是写脚本
    调用接口时,生产环境,路径加斜杠“/”和不加的区别
    WPF 踩坑笔记12 DataGrid触发选中行事件
    WPF 踩坑笔记11 线程取消
    WPF 踩坑笔记10 ListBox异步动态加载
    WPF 踩坑笔记9 直接打印
    思维的体操
    【洛谷 P4213】 【模板】杜教筛(Sum)
    【洛谷 P2257】 YY的GCD(莫比乌斯反演)
    【洛谷 P4980】 【模板】Pólya 定理
  • 原文地址:https://www.cnblogs.com/chxer/p/4426226.html
Copyright © 2011-2022 走看看