Richard21477 @ 2020-07-17 09:49:30
#include<bits/stdc++.h>
using namespace std;
struct node{
int l;
int r;
int num;
int key;
int s;
bool laz;
};
node all[100000];
int root;
int cnt=0;
int nes(int x){//return loc
all[++cnt].s=1;
all[cnt].num=x;
all[cnt].key=rand();
all[cnt].laz=false;
return cnt;
}
void done(int loc){
if (all[loc].laz){
all[loc].laz=false;
all[all[loc].l].laz=!all[all[loc].l].laz;
all[all[loc].r].laz=!all[all[loc].r].laz;
}
return;
}
void update(int loc){
all[loc].s=all[all[loc].l].s+all[all[loc].r].s+1;
return;
}
/*void split(int loc,int val,int &x,int &y){//from <=val;x->l's r;y->r's l;also root
if (loc==0){
x=y=0;
return;
}
if (val>=all[loc].num){
x=loc;
split(all[loc].r,val,all[loc].r,y);
}
else{
y=loc;
split(all[loc].l,val,x,all[loc].l);
}
update(loc);
}*/
void split(int loc,int sze,int &x,int &y){
if (loc==0){
x=y=0;
return;
}
done(loc);
if (all[all[loc].l].s>=sze){
y=loc;
split(all[loc].l,sze,x,all[loc].l);
}
else{
x=loc;
split(all[loc].r,sze,all[loc].r,y);
}
update(loc);
}
int merge(int le,int ri){//le << ri,return root
if (le==0||ri==0)
return le+ri;//l or r
done(le);
done(ri);
if (all[le].key<=all[ri].key){
all[ri].l=merge(le,all[ri].l);
update(ri);
return ri;
}
else{
all[le].r=merge(all[le].r,ri);
update(le);
return le;
}
}
int x,y,z;
int opp[100001];
int ins(int ll,int rr){
if (ll>rr){
return 0;
}
int mid=(ll+rr)>>1;
int ro1=nes(mid);
all[ro1].l=ins(ll,mid-1);
all[ro1].r=ins(mid+1,rr);
return ro1;
}
void rev(int l,int r){
split(root,r,x,z);
split(root,l-1,x,y);
all[y].laz=!all[y].laz;
root=merge(merge(x,y),z);
return;
}
void print(int loc){
if (loc==0)
return;
done(loc);
print(all[loc].l);
printf("%d ",all[loc].num);
print(all[loc].r);
return;
}
/*void ins(int val){
split(root,val,x,y);
root=merge(merge(x,nes(val)),y);
}
void del(int val){
split(root,val,x,z);
split(x,val-1,x,y);//y->val
y=merge(all[y].l,all[y].r);
root=merge(merge(x,y),z);
return;
}
int askrank(int val){
split(root,val-1,x,y);
int ret=all[x].s+1;
root=merge(x,y);
return ret;
}
int asknum(int rk){
int f=root;
while (f!=0){
if (all[all[f].l].s+1==rk)
break;
if (all[all[f].l].s+1>rk)
f=all[f].l;
else{
rk-=all[all[f].l].s+1;
f=all[f].r;
}
}
return all[f].num;
}
int bef(int val){
split(root,val-1,x,y);
int f=x;
while (all[f].r!=0){
f=all[f].r;
}
int ret=all[f].num;
root=merge(x,y);
return ret;
}
int aft(int val){
split(root,val,x,y);
int f=y;
while (all[f].l!=0){
f=all[f].l;
}
int ret=all[f].num;
root=merge(x,y);
return ret;
}*/
int main(){
srand(time(0));
int n,m;
cin>>n>>m;
root=ins(1,n);
for (int i=0;i<m;i++){
int a,b;
scanf("%d%d",&a,&b);
rev(a,b);
}
print(root);
return 0;
}
by Hauynite @ 2020-07-17 10:04:18
@Richard21477
split
中,split(all[loc].r,sze,all[loc].r,y);
改为split(all[loc].r,sze-all[all[loc].l].s-1,all[loc].r,y);
。这里的sze是相对当前的loc而言的,包括了loc的左子树大小和本身节点的1,向右递归时要减掉。
done
中all[loc].laz=false;
后面加一句swap(all[loc].l,all[loc].r);
,交换左右儿子才能起到翻转作用
ins函数return ro1;
前需要update(ro1);
rev
函数中第二行split改为split(x,l-1,x,y);
。此时根已经分裂掉了,不能再用,应在包含l的x内分裂。