这题涉及到区间操作 emmm Splay可以很好胜任
不过谢谢非旋转treap的把 操作和之前的treap(不好意思没发 因为用非旋重新实现了之前的普通平衡树
之前down忘记在split里操作 WA了一发
看代码把
/*
luogu 3369
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <stack>
#include <set>
#include <algorithm>
#include <sstream>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int MAX_N = 500010;
int siz[MAX_N],ch[MAX_N][2],rnd[MAX_N],val[MAX_N],fl[MAX_N];
int T,cnt,m,x,y,z,p,a,root,rt,com;
int read(){
int x = 0,f = 1;char c = getchar();
while(c>'9'||c<'0') {if(c=='-') f =-1;c = getchar();}
while(c>='0'&&c<='9') {x = x*10 + c - '0';c = getchar();}
return x * f;
}
void update(int x){
siz[x] = 1 + siz[ch[x][0]] + siz[ch[x][1]];
}
void down(int now){
swap(ch[now][0],ch[now][1]);
if(ch[now][0]) fl[ch[now][0]]^=1;
if(ch[now][1]) fl[ch[now][1]]^=1;
fl[now] = 0;
}
int Insert(int a){
siz[++cnt] = 1;
val[cnt] = a;
rnd[cnt] = rand();
return cnt;
}
int Merge(int A,int B){
if(!A||!B) return A+B;
if(rnd[A]<rnd[B]) {if(fl[A]) down(A);ch[A][1] = Merge(ch[A][1],B);update(A);return A;}
else {if(fl[B]) down(B);ch[B][0] = Merge(A,ch[B][0]);update(B);return B;}
}
void split(int now,int k,int &x,int &y){
if(!now) x = y = 0;
else {
if(fl[now]) down(now);
if(k<=siz[ch[now][0]]){
y = now;
split(ch[now][0],k,x,ch[now][0]);
}
else {
x = now;
split(ch[now][1],k-siz[ch[now][0]]-1,ch[now][1],y);
}
update(now);
}
}
void coutt(int now){
if(!now) return;
if(fl[now]) down(now);
coutt(ch[now][0]);
printf("%d ",val[now]);
coutt(ch[now][1]);
}
int main(){
int n;
n = read();m =read();
for(int i = 1;i<=n;++i)
rt = Merge(rt,Insert(i));
while(m--){
int l,r,a,b,c;
l = read(),r =read();
split(rt,l-1,a,b);
split(b,r-l+1,b,c);
fl[b]^=1;
rt = Merge(a,Merge(b,c));
}
coutt(rt);
return 0;
}