FHQ-Treap
要啥splay?
【模板】文艺平衡树:https://www.luogu.org/problem/P3391
FHQ维护区间,每次将区间拆成[1,l-1],[l,r],[r+1,n],然后把[l,r]打上标记即可
最后中序遍历
#define B cout << "breakpoint" << endl; #define O(x) cout << #x << " " << x << endl; #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<cstdlib> using namespace std; inline int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op; } const int maxn = 1e5 + 5; #define ls ch[now][0] #define rs ch[now][1] int ch[maxn][2],sz[maxn],val[maxn],key[maxn],tag[maxn],tot,rt; inline int New(int k) { key[++tot] = rand(),val[tot] = k,sz[tot] = 1; return tot; } inline int up(int now) { return sz[now] = sz[ls] + sz[rs] + 1; } inline void down(int now) { if(!tag[now]) return; swap(ls,rs); tag[ls] ^= 1,tag[rs] ^= 1; tag[now] = 0; } void split(int now,int k,int &x,int &y)//x < k,y > k { if(!now) { x = y = 0; return; } down(now); if(sz[ls] < k) x = now,split(rs,k - sz[ls] - 1,rs,y); else y = now,split(ls,k,x,ls); up(now); } int merge(int x,int y)//小根堆,x <= y { if(!x || !y) return x + y; if(key[x] < key[y]) { down(x); ch[x][1] = merge(ch[x][1],y); up(x); return x; } else { down(y); ch[y][0] = merge(x,ch[y][0]); up(y); return y; } } void solve(int now) { if(!now) return; down(now); solve(ls); printf("%d ",val[now]); solve(rs); } int main() { int n = read(),m = read(); for(int i = 1;i <= n;i++) rt = merge(rt,New(i)); for(int i = 1;i <= m;i++) { int l = read(),r = read(); int x,y,z; split(rt,l - 1,x,y); split(y,r - l + 1,y,z); tag[y] ^= 1; rt = merge(x,merge(y,z)); } solve(rt); }