区间的操作最主要的地方就是把 split 操作从按权值分裂 改成了 按大小分裂

 

我们把 大小 == k 放在一棵树,然后其余的放在另一棵树

 

  1 #include <stdio.h>
  2 #include <iostream>
  3 #include <string.h>
  4 #include <random>
  5 
  6 const int maxn = 1e5 + 10;
  7 
  8 struct Node {
  9     int l,r;
 10     int val,key;
 11     int size;
 12     bool reverse;
 13 }fhq[maxn];
 14 
 15 int cnt,root;
 16 
 17 std::mt19937 rnd(233);
 18 
 19 int newnode(int val) {
 20     fhq[++cnt].val = val;
 21     fhq[cnt].key = rnd();
 22     fhq[cnt].size = 1;
 23     return cnt;
 24 }
 25 
 26 void update(int now) {
 27     fhq[now].size = fhq[fhq[now].l].size + fhq[fhq[now].r].size + 1;
 28 }
 29 
 30 void pushdown(int now) {
 31     std::swap(fhq[now].l,fhq[now].r);
 32     fhq[fhq[now].l].reverse^=1;
 33     fhq[fhq[now].r].reverse^=1;
 34     fhq[now].reverse = false;
 35 }
 36 
 37 void split(int now,int siz,int &x,int &y) {
 38     if (!now)
 39         x = y = 0;
 40     else {
 41         if (fhq[now].reverse) {
 42             pushdown(now);
 43         }
 44         if (fhq[fhq[now].l].size < siz) {
 45             x = now;
 46             split(fhq[now].r,siz-fhq[fhq[now].l].size-1,fhq[now].r,y);
 47         }
 48         else {
 49             y = now;
 50             split(fhq[now].l,siz,x,fhq[now].l);
 51         }
 52         update(now);
 53     }
 54 }
 55 
 56 int merge(int x,int y) {
 57     if (!x || !y)
 58         return x + y;
 59     if (fhq[x].key > fhq[y].key) {
 60         if (fhq[x].reverse)
 61             pushdown(x);
 62         fhq[x].r = merge(fhq[x].r,y);
 63         update(x);
 64         return x;
 65     }
 66     else {
 67         if (fhq[y].reverse)
 68             pushdown(y);
 69         fhq[y].l = merge(x,fhq[y].l);
 70         update(y);
 71         return y;
 72     }
 73 }
 74 
 75 void reverse(int l,int r) {
 76     int x,y,z;
 77     split(root,l-1,x,y);
 78     split(y,r-l+1,y,z);
 79     fhq[y].reverse^=1;
 80     root = merge(merge(x,y),z);
 81 }
 82 
 83 void ldr(int now) {
 84     if (!now)
 85         return ;
 86     if (fhq[now].reverse)
 87         pushdown(now);
 88     ldr(fhq[now].l);
 89     printf("%d ",fhq[now].val);
 90     ldr(fhq[now].r);
 91 }
 92 
 93 int main() {
 94     int n,m;
 95     scanf("%d%d",&n,&m);
 96     for (int i=1;i<=n;i++) {
 97         root = merge(root,newnode(i));
 98     }
 99     while (m--) {
100         int l,r;
101         scanf("%d%d",&l,&r);
102         reverse(l,r);
103     }
104     ldr(root);
105     return 0;
106 }