平衡树板子

总览

  1. 长达146km的代码
  2. 长达134km的代码
  3. 长达88km的代码
  4. 这个是个 0
  5. 长达124cm的代码
  6. 长达126km的代码
  7. 长达93mm的代码
  8. 长达66um的代码

替罪羊

#include <algorithm>
#include <iostream>

using namespace std;

const int MaxN = 4e5 + 10;
const double eps = 0.75;

int d[MaxN], l[MaxN], r[MaxN], cnt[MaxN], sum[MaxN], sz[MaxN], a[MaxN], tot, n, root, len;

void update(int x) {  // 更新
  sum[x] = sum[l[x]] + sum[r[x]] + cnt[x];
  sz[x] = sz[l[x]] + sz[r[x]] + 1;
}

bool Check(int x) {  // 判断是否需要重构
  return cnt[x] && 1.0 * max(sz[l[x]], sz[r[x]]) > eps * sz[x];
}

void dfs(int x) {  // 中序遍历
  if (!x) {
    return;
  }
  dfs(l[x]);
  cnt[x] && (a[++len] = x);
  dfs(r[x]);
}

int build(int pl, int pr) {  // 二分重构
  if (pl > pr) {
    return 0;
  }
  int mid = (pl + pr) >> 1;
  l[a[mid]] = build(pl, mid - 1);
  r[a[mid]] = build(mid + 1, pr);
  update(a[mid]);
  return a[mid];
}

int G(int k) {
  len = 0;
  dfs(k);
  return k = build(1, len);
}

void insert(int &k, int x) {  // 添加
  if (!k) {
    k = ++tot;
    (!root) && (root = tot);
    d[tot] = x, l[tot] = r[tot] = 0, sum[tot] = cnt[tot] = sz[tot] = 1;
    return;
  }
  if (d[k] == x) {
    cnt[k]++;
  } else if (d[k] < x) {
    insert(r[k], x);
  } else {
    insert(l[k], x);
  }
  update(k);
  if (Check(k)) {
    k = G(k);
  }
}

void delet(int &k, int x) {  // 删除
  if (!k) {
    return;
  }
  if (d[k] == x) {
    cnt[k] && (cnt[k]--);
  } else if (d[k] < x) {
    delet(r[k], x);
  } else {
    delet(l[k], x);
  }
  update(k);
  if (Check(k)) {
    k = G(k);
  }
}

int At(int k, int x) {  // @
  if (!k) {
    return 0;
  }
  if (sum[l[k]] < x && x <= sum[l[k]] + cnt[k]) {
    return d[k];
  } else if (sum[l[k]] + cnt[k] < x) {
    return At(r[k], x - sum[l[k]] - cnt[k]);
  }
  return At(l[k], x);
}

int upbd(int k, int x) {  // 大于
  if (!k) {
    return 1;
  }
  if (d[k] == x && cnt[k]) {
    return sum[l[k]] + cnt[k] + 1;
  } else if (x < d[k]) {
    return upbd(l[k], x);
  }
  return upbd(r[k], x) + sum[l[k]] + cnt[k];
}

int upgrt(int k, int x) {  // 小于
  if (!k) {
    return 0;
  }
  if (d[k] == x && cnt[k]) {
    return sum[l[k]];
  } else if (d[k] < x) {
    return upgrt(r[k], x) + sum[l[k]] + cnt[k];
  }
  return upgrt(l[k], x);
}

int p(int x) {  // 前驱
  return At(root, upgrt(root, x));
}

int h(int x) {  // 后继
  return At(root, upbd(root, x));
}

int main() {
  cin >> n;
  for (int op, x; n; n--) {
    cin >> op >> x;
    if (op == 1) {
      insert(root, x);
    } else if (op == 2) {
      delet(root, x);
    } else if (op == 3) {
      cout << upgrt(root, x) + 1 << '\n';
    } else if (op == 4) {
      cout << At(root, x) << '\n';
    } else if (op == 5) {
      cout << p(x) << '\n';
    } else {
      cout << h(x) << '\n';
    }
  }
  return 0;
}

旋转Treap

#include <ctime>
#include <iostream>
#include <random>

using namespace std;

const int MaxN = 1e5 + 10;

struct Node {
  int d, v, l, r, sum, cnt;
} w[MaxN];

int n, root, tot;

void update(int x) {
  w[x].sum = w[w[x].l].sum + w[w[x].r].sum + w[x].cnt;
}

void left(int &k) {
  int p = w[k].l;
  w[k].l = w[p].r, w[p].r = k, k = p;
  update(w[k].r), update(k);
}

void right(int &k) {
  int p = w[k].r;
  w[k].r = w[p].l, w[p].l = k, k = p;
  update(w[k].l), update(k);
}

void insert(int &k, int x) {
  if (!k) {
    k = ++tot;
    w[k] = {x, rand(), 0, 0, 1, 1};
    return;
  }
  if (w[k].d == x) {
    w[k].cnt++;
  } else if (w[k].d < x) {
    insert(w[k].r, x);
    if (w[w[k].r].v < w[k].v) {
      right(k);
    }
  } else {
    insert(w[k].l, x);
    if (w[w[k].l].v < w[k].v) {
      left(k);
    }
  }
  update(k);
}

void delet(int &k, int x) {
  if (!k) {
    return;
  }
  if (w[k].d == x) {
    if (w[k].cnt) {
      w[k].cnt--, update(k);
    } else if (w[k].l || w[k].r) {
      if (!w[k].r || w[w[k].l].d > w[w[k].r].d) {
        left(k), delet(w[k].l, x);
      } else {
        right(k), delet(w[k].r, x);
      }
      update(k);
    } else {
      k = 0;
    }
  }
  if (w[k].d < x) {
    delet(w[k].r, x);
  } else {
    delet(w[k].l, x);
  }
  update(k);
}

int upbd(int k, int x) {
  if (!k) {
    return 1;
  }
  if (w[k].d == x) {
    return w[w[k].l].sum + w[k].cnt + 1;
  } else if (w[k].d < x) {
    return upbd(w[k].r, x) + w[w[k].l].sum + w[k].cnt;
  }
  return upbd(w[k].l, x);
}
int upgrt(int k, int x) {
  if (!k) {
    return 0;
  }
  if (w[k].d == x) {
    return w[w[k].l].sum;
  } else if (x < w[k].d) {
    return upgrt(w[k].l, x);
  }
  return upgrt(w[k].r, x) + w[w[k].l].sum + w[k].cnt;
}

int At(int k, int x) {
  if (!k) {
    return 0;
  }
  if (w[w[k].l].sum < x && x <= w[w[k].l].sum + w[k].cnt) {
    return w[k].d;
  } else if (w[w[k].l].sum + w[k].cnt < x) {
    return At(w[k].r, x - w[w[k].l].sum - w[k].cnt);
  }
  return At(w[k].l, x);
}

int main() {
  srand(time(NULL));
  cin >> n;
  for (int op, x; n; n--) {
    cin >> op >> x;
    if (op == 1) {
      insert(root, x);
    } else if (op == 2) {
      delet(root, x);
    } else if (op == 3) {
      cout << upgrt(root, x) + 1 << '\n';
    } else if (op == 4) {
      cout << At(root, x) << '\n';
    } else if (op == 5) {
      cout << At(root, upgrt(root, x)) << '\n';
    } else {
      cout << At(root, upbd(root, x)) << '\n';
    }
  }
  return 0;
}

FHQ

#include <iostream>
#include <ctime>

using namespace std;

const int MaxN = 2e6 + 10;

struct S {
	int x, v, ls, rs, sum;
} a[MaxN];

int rt, tot, t, n, ans;

int update(int k) {
	return a[k].sum = k ? a[a[k].ls].sum + a[a[k].rs].sum + 1 : 0, k;
}

void split(int k, int v, int &x, int &y) {
	if (!k) return;
	int l = a[k].ls, r = a[k].rs;
	((a[k].x <= v) ? (split(r, v, a[k].rs = 0, y), x) : (split(l, v, x, a[k].ls = 0), y)) = k;
	update(k);
}

int merge(int x, int y) {
	if (!x || !y) return x | y;
	return update((a[x].v <= a[y].v) ? (a[x].rs = merge(a[x].rs, y), x) : (a[y].ls = merge(x, a[y].ls), y));
}

void insert(int v, int x = 0, int y = 0) {
	split(rt, v, x, y);
	a[++tot] = {v, rand(), 0, 0, 1};
	rt = merge(merge(x, tot), y);
}

void delet(int &k, int x) {
  if (a[k].x == x) {
    k = merge(a[k].ls, a[k].rs);
  } else {
    a[k].x <= x ? delet(a[k].rs, x) : delet(a[k].ls, x);
    update(k);
  } 
}

int upgrt(int k, int x) {
	if (!k) return 0;
	if (a[k].x >= x) {
		return upgrt(a[k].ls, x);
	}
	return upgrt(a[k].rs, x) + a[a[k].ls].sum + 1;
}
 
int shit2(int k, int x) {
  	if (!k) return 0;
	if (x == a[a[k].ls].sum + 1) {
		return a[k].x;
	} else if (a[a[k].ls].sum + 1 < x) {
		return shit2(a[k].rs, x - a[a[k].ls].sum - 1);
	}
	return shit2(a[k].ls, x);
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	srand(time(NULL));
	cin >> n >> t;
	for (int i = 1, x; i <= n; i++) {
		cin >> x, insert(x);
	}
	for (int op, x, lst = 0; t; t--) {
		cin >> op >> x, x ^= lst;
		if (op == 1) {
			insert(x);
		} else if (op == 2) {
			delet(rt, x); 
		} else if (op == 3) {
			ans ^= (lst = upgrt(rt, x) + 1);
		} else if (op == 4) {
			ans ^= (lst = shit2(rt, x));
		} else if (op == 5) {
      		ans ^= (lst = shit2(rt, upgrt(rt, x)));
    	} else {
      		ans ^= (lst = shit2(rt, upgrt(rt, x + 1) + 1));
		}
	}
	cout << ans << endl;
	return 0;
} 

平板电视 \(pb\_ds\)

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;

typedef int pii;

void tree_test()
{
    tree<pii,null_type,less<pii>,rb_tree_tag,tree_order_statistics_node_update> t,nt;
    
    //可遍历: for(xx::iterator it=t.begin();it!=t.end();it++)
    //一些正常的函数: t.clear(); t.empty(); t.find();
     
    //插入: t.insert(x);
    //所有元素不可重 
    
    //删除: t.erase(x);
    
    //排名: t.order_of_key(x);
    //返回【严格小于】x的数的个数 
    
    //kth: t.find_by_order(k);
    //返回从小到大第k个数的iterator【从0开始】 
    //当k>=sz时返回t.end() 
    
    //lower_bound: t.lower_bound(x);
    //*it>=x
    
    //upper_bound: t.upper_bound(x);
    //*it>x
    
    //合并: t.join(nt);
    //将nt合并进入t,之后nt清空 
    //t,nt需要类型相同,且值域不重合
    
    //分裂: t.split(x,nt);
    //将<=x的元素留在t中,其余放到nt中
    //会将nt中原有元素扔掉 
}

void priority_queue_test()
{
    //小根堆greater<pii> 大根堆less<pii>
    __gnu_pbds::priority_queue<pii,std::less<pii>,pairing_heap_tag> Q,nQ;
    
    //可遍历: for(xx::iterator it=Q.begin();it!=Q.end();it++)
    //遍历顺序与堆的性质相反
    
    //基本函数: Q.push(x); Q.pop(); Q.top(); Q.clear(); Q.empty(); Q.size();
    
    //合并: Q.join(nQ);
    //会把nQ清空 
}

void hash_test()
{
    gp_hash_table<string,int> mp;
    
    //可遍历: for(xx::iterator it=mp.begin();it!=mp.end();it++)
    //it->first it->second
    //【遍历顺序不按第一关键字】 
    
    //经典用法: mp["rlstxdy"]=666;
    //基本函数: mp.size(); mp.empty(); 
}

int main()
{
    tree_test();
    hash_test();
    priority_queue_test();
}

FHQ 进阶

#include <iostream>
#include <ctime>

using namespace std;

const int MaxN = 2e5 + 10;

struct tree {
  struct S {
    int w, v, l, r, sum, tag, fa; 
    char c; // __builtin_popcount
  } a[MaxN];

  int tot, root;
  bool vis[MaxN];

  int update(int k) {
    (a[k].l) && (a[a[k].l].fa = k), (a[k].r) && (a[a[k].r].fa = k);
    a[k].fa = 0;
    return (k) && (a[k].sum = a[a[k].l].sum + a[a[k].r].sum + 1, a[k].w = a[a[k].l].w | a[a[k].r].w | (1 << (a[k].c - 'a'))), k;
  }

  void pd(int k) {
    if (!a[k].tag) return;
    swap(a[k].l, a[k].r);
    a[a[k].l].tag ^= 1, a[a[k].r].tag ^= 1;
    a[k].tag = 0;
  }

  int split(int k, int v, int &x, int &y, int l = 0, int r = 0) {
    if (!k) return x = y = 0;
    pd(k), l = a[k].l, r = a[k].r;
    ((a[l].sum + 1 <= v) ? (split(r, v - a[l].sum - 1, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k;
    return update(k);
  }

  int merge(int x, int y) {
    if (!x || !y) return x | y;
    return update((a[x].v < a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y));
  }

  void insert(int id, char c, int s = 0, int b = 0) {
    split(root, id, s, b);
    a[++tot] = {(1 << (c - 'a')), rand(), 0, 0, 1, 0, 0, c};
    root = merge(merge(s, tot), b), vis[tot] = 1;
  }

  void erase(int id, int k = 0, int y = 0, int n = 0) {
    split(root, id - 1, k, n);
    split(n, 1, y, n);
    vis[y] = 0;
    root = merge(k, n);
  }

  int query(int l, int r, int k = 0, int y = 0, int n = 0) {
    split(root, r, k, n);
    split(k, l - 1, k, y);
    int res = a[y].w;
    root = merge(merge(k, y), n);
    return __builtin_popcount(res);
  }

  void reverse(int l, int r, int k = 0, int y = 0, int n = 0) {
    split(root, r, k, n);
    split(k, l - 1, k, y);
    a[y].tag ^= 1;
    root = merge(merge(k, y), n);
  }

  char At(int k, int x) {
    if (!k) return 0;
    pd(k);
    if (a[a[k].l].sum + 1 < x) {
      return At(a[k].r, x - a[a[k].l].sum - 1);
    } else if (a[a[k].l].sum >= x) {
      return At(a[k].l, x);
    }
    return a[k].c;
  }

  bool DFS(int x) {
    if (!x) return 1;
    DFS(a[x].fa), pd(x);
    return 1;
  }

  int Gk(int k, bool flag = 1) {
    if (!vis[k] || k == root) return 0;
    (flag) && (DFS(k));
    return Gk(a[k].fa, 0) + flag * (a[a[k].l].sum + 1) + (a[a[k].fa].r == k) * (a[a[a[k].fa].l].sum + 1);
  }
} tr;

int n, m;
string s;

int main() {
  srand(time(NULL));
  cin >> n >> m >> s;
  for (int i = 0; i < n; i++) {
    tr.insert(i + 1, s[i]);
  }
  for (int x, y; m; m--) {
    char op, c;
    cin >> op >> x;
    if (op == 'I') {
      cin >> c;
      tr.insert(x, c);
    } else if (op == 'D') {
      tr.erase(x);
    } else if (op == 'R') {
      cin >> y;
      tr.reverse(x, y);
    } else if (op == 'P') {
      cout << tr.Gk(x) << endl;
    } else if (op == 'T') {
      cout << tr.At(tr.root, x) << endl;
    } else {
      cin >> y;
      cout << tr.query(x, y) << endl;
    }
  }
  return 0;
}

splay

#include <iostream>

using namespace std;

const int MaxN = 1e6 + 1e5 + 10;

struct Tree {
  struct Node {
    int w, ch[2], fa, cnt, sum, tag, x;
  } a[MaxN];

  int tot, root, l, r;

  Node operator[](int k) {
    return a[k];
  }

  void update(int k) {
    a[k].sum = a[a[k].ch[0]].sum + a[a[k].ch[1]].sum + a[k].cnt;
  }
  
  void pushdown(int k) {
  	if (a[k].tag) {
  	  swap(a[k].ch[0], a[k].ch[1]);
  	  a[a[k].ch[1]].tag ^= 1;
  	  a[a[k].ch[0]].tag ^= 1;
  	  a[k].tag = 0;
	  }
  }

  void rotatr(int x) {
    int y = a[x].fa, z = a[y].fa, k = a[y].ch[1] == x;
    a[z].ch[y == a[z].ch[1]] = x, a[x].fa = z;
    a[y].ch[k] = a[x].ch[k ^ 1], a[a[x].ch[k ^ 1]].fa = y;
    a[x].ch[k ^ 1] = y, a[y].fa = x;
    update(y);
  }

  void splay(int x, int to = 0) {
    for (int y, z; a[x].fa != to; y = a[x].fa, z = a[y].fa, (z != to) ? (((y == a[z].ch[1]) ^ (x == a[y].ch[1])) ? rotatr(x) : rotatr(y)) : void(), rotatr(x)) {
    }
    update(x), (to) || (root = x);
  }

  int At(int x) {
    int k = root;
    if (!k) return k;
    for (; (pushdown(k), a[k].ch[x > a[k].x]) && a[k].x != x; k = a[k].ch[x > a[k].x]) {
    }
    return splay(k), k;
  }

  void insert(int x) {
    int k = root, y = 0;
    for (; k && a[k].x != x; y = k, k = a[k].ch[x > a[k].x]) {
    }
    (k) ? (a[k].cnt++) : (k = ++tot, a[k] = {x, {0, 0}, y, 1, 1, 0, x}, (y) && (a[y].ch[x > a[y].x] = k));
    splay(k);
  }

  Tree() {
    root = tot = 0;
    a[0] = {0, {0, 0}, 0, 0, 0, 0};
    insert(-2e9), insert(2e9);
  }

  int kth(int x) {
    int k = root;
    for (int tx, kll; (pushdown(k), k) && !(a[a[k].ch[0]].sum < x && x <= a[a[k].ch[0]].sum + a[k].cnt); kll = a[k].cnt + a[a[k].ch[0]].sum, tx = x, (kll < tx) && (x -= kll), k = a[k].ch[kll < tx]) {
    }
    return splay(k), k;
  }

  int pn(int x, bool flag) {  // 0 为前驱,1 为后继
    At(x);
    int k = root;
    if (a[k].x > x && flag || a[k].x < x && !flag) return splay(k), k;
    k = a[k].ch[flag];
    for (; a[k].ch[!flag]; k = a[k].ch[!flag]) {
    }
    return splay(k), k;
  }

  void erase(int x) {
    int pre = pn(x, 0), nxt = pn(x, 1);
    splay(pre), splay(nxt, pre);
    int k = a[nxt].ch[0];
    if (a[k].cnt > 1) {
      a[k].cnt--;
      splay(k);
    } else {
      a[nxt].ch[0] = 0;
      splay(nxt);
    }
  }
  
  void reverse(int l, int r){
    l = kth(l), r = kth(r + 2);
    splay(l), splay(r, l);
    a[a[r].ch[0]].tag ^= 1;
  }
  
  void DFS(int x) {
    if (!x) return;
    pushdown(x);
    DFS(a[x].ch[0]);
    if (a[x].x != -2e9 && a[x].x != 2e9) cout << a[x].x << " ";
    DFS(a[x].ch[1]);
  }
} tree;

int n, m, ans;

int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    tree.insert(i);
  }
  for (int i = 1, l, r; i <= m; i++) {
    cin >> l >> r;
    tree.reverse(l, r);
  }
  tree.DFS(tree.root);
  return 0;
}

FHQ 进阶2

#include <iostream>
#include <ctime>
 
using namespace std;
 
const int MaxN = 2e5 + 10;
 
struct Tree {
  struct Node {
    int w, v, l, r, sum, tag;
  } a[MaxN];
 
  int root, tot;
 
  int update(int k) {
    return a[k].sum = k ? a[a[k].l].sum + a[a[k].r].sum + 1 : 0, k;
  }
 
  void pd(int k) {
    a[a[k].l].w += a[k].tag, a[a[k].l].tag += a[k].tag;
    a[a[k].r].w += a[k].tag, a[a[k].r].tag += a[k].tag;
    a[k].tag = 0;
  }
 
  void split(int k, int v, int &x, int &y, int l = 0, int r = 0) {
    if (!k) return;
    pd(k), l = a[k].l, r = a[k].r;
    ((a[k].w <= v) ? (split(r, v, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k;
    update(k);
  }
 
  int merge(int x, int y) {
    if (!x || !y) return x | y;
    return update((a[x].v > a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y));
  }
 
  void insert(int w, int x = 0, int y = 0) {
    a[++tot] = {w, rand(), 0, 0, 1, 0};
    split(root, w, x, y);
    root = merge(merge(x, tot), y);
  }
 
  void G(int w) {
  	a[root].w += w, a[root].tag += w;
  }
 
  int At(int k, int x) {
    if (!k) return -1;
    pd(k);
    if (a[a[k].r].sum + 1 < x) {
      return At(a[k].l, x - a[a[k].r].sum - 1);
    } else if (a[a[k].r].sum >= x) {
      return At(a[k].r, x);
    }
    return a[k].w;
  }
 
  int upgrt(int k, int x) {
  	if (!k) return 0;
  	pd(k);
  	if (x <= a[k].w) {
  		return upgrt(a[k].l, x);
	}
	return upgrt(a[k].r, x) + a[a[k].l].sum + 1;
  }
} tr;

int t, x, gz, ans;
char op;
 
int main() {
  srand(time(NULL));
  for (cin >> t >> gz; t; t--) {
  	cin >> op >> x;
  	if (op == 'I') {
  		if (x >= gz) {
			tr.insert(x);
		}
	} else if (op == 'A') {
		tr.G(x);
	} else if (op == 'S') {
		tr.G(-x);
		int s = 0, b = 0;
		tr.split(tr.root, gz - 1, s, b);
		ans += tr.a[s].sum;
		tr.root = b;
	} else {
		cout << tr.At(tr.root, x) << endl;
	}
  }
  cout << ans << endl;
  return 0;
}

暴力加减如何呢?

文艺平衡树

只记录了一个题目的,用法太少了,所以我选择补一个完全没必要的

#include <iostream>
#include <ctime>

using namespace std;

const int MaxN = 100010;

struct S {
	int v, l, r, sum, tag;
} a[MaxN];

int root, tot, n, m;

int update(int k) {
	return (k) && (a[k].sum = a[a[k].l].sum + a[a[k].r].sum + 1), k;
}

void pd(int k) {
	if (!a[k].tag) return;
	swap(a[k].l, a[k].r);
	a[a[k].l].tag ^= 1;
	a[a[k].r].tag ^= 1;
	a[k].tag = 0;
}

int split(int k, int v, int &x, int &y, int l = 0, int r = 0) {
	if (!k) return x = y = 0;
	pd(k), l = a[k].l, r = a[k].r;
	((a[l].sum + 1 <= v) ? (split(r, v - 1 - a[l].sum, a[k].r = 0, y), x) : (split(l, v, x, a[k].l = 0), y)) = k;
	return update(k); 
}

int merge(int x, int y) {
	if (!x || !y) return x | y;
	return update((a[x].v < a[y].v) ? (pd(x), a[x].r = merge(a[x].r, y), x) : (pd(y), a[y].l = merge(x, a[y].l), y));
}

void reverse(int l, int r) {
	int tmp1 = 0, tmp2 = 0, tmp3 = 0;
	split(root, r, tmp1, tmp3);
	split(tmp1, l - 1, tmp1, tmp2);
	a[tmp2].tag ^= 1;
	root = merge(merge(tmp1, tmp2), tmp3);
}

void DFS(int x) {
	if (!x) return;
	pd(x);
	DFS(a[x].l);
	cout << x << " ";
	DFS(a[x].r);
}

int main() {
	srand(time(NULL));
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		a[i] = {rand(), 0, 0, 1, 0};
		root = merge(root, i);
	}
	for (int i = 1, l, r; i <= m; i++) {
		cin >> l >> r;
		reverse(l, r);
	}
	DFS(root);
	return 0;
}
posted @ 2023-08-17 23:46  yabnto  阅读(54)  评论(0)    收藏  举报