题目link:
1)http://www.lydsy.com/JudgeOnline/problem.php?id=3223
2) https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3073
splay标准操作:区间翻转与合并
注意建立虚点满足分割时左子树不为空的限制
BZOJ 3223
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 100005;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
typedef long long ll;
int l,r,sz,rt;
int f[maxn];
int ch[maxn][2];
int val[maxn];
int Size[maxn];
int flip[maxn];
vector<int> ans;
int get(int x){
return ch[f[x]][1]==x;
}
void update(int x){
if(x){
Size[x]=1;
if(ch[x][0]) Size[x]+=Size[ch[x][0]];
if(ch[x][1]) Size[x]+=Size[ch[x][1]];
}
}
void init(){
for(int i=0;i<=sz;i++){
ch[i][0]=ch[i][1]=Size[i]=flip[i]=0;
}
rt=sz=0;
}
void pushdown(int x){
if(flip[x]){
swap(ch[x][0],ch[x][1]);
flip[ch[x][0]]=!flip[ch[x][0]];
flip[ch[x][1]]=!flip[ch[x][1]];
flip[x]=0;
}
}
void rotate(int x){
int y=f[x];
int z=f[y];
int k = get(x);
ch[y][k]=ch[x][k^1]; f[ch[y][k]]=y;
f[y]=x;ch[x][k^1]=y;
f[x]=z;
if(z) ch[z][ch[z][1]==y]=x;
update(y);
update(x);
}
void splay(int x){
int y;
int z;
// pushdown(x);
while(y=f[x]){
// pushdown(y);
z=f[y];
if(z){
// pushdown(z);
if(get(x)==get(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
rt=x;
}
void insert(int v){
if(rt==0){
sz++;
ch[sz][0]=ch[sz][1]=f[sz]=0;
val[sz]=v;Size[sz]=1;rt=sz;
return;
}
int x=rt;
while(true){
int y=ch[x][val[x]<v];
if(y==0){
sz++;
ch[sz][0]=ch[sz][1]=0;
val[sz]=v;Size[sz]=1;
f[sz]=x;ch[x][val[x]<v]=sz;
splay(sz);
break;
}
x=y;
}
}
int find_k(int tr,int x){
int now=tr;
while(true){
pushdown(now);
if(ch[now][0]&&x<=Size[ch[now][0]]){
now=ch[now][0];
}else {
int tmp=(ch[now][0]?Size[ch[now][0]]:0)+1;
if(x==tmp) return now;
x-=tmp;
now=ch[now][1];
}
}
}
int build(int len){
// cout<<"pre "<<len<<' '<<sz<<endl;
if(!len) return 0;
int l=build(len>>1);
int o = ++sz;
// cout<<len<<' '<<o<<endl;
val[o]=sz;
ch[o][0]=l;
ch[o][1]=build(len-(len>>1)-1);
f[ch[o][0]]=f[ch[o][1]]=o;
flip[o]=Size[o]=0;
update(o);
return o;
}
void split(int o,int k,int& l,int& r){
int tr = find_k(o,k);
// cout<<"split "<<tr<<' '<<val[tr]<<endl;
splay(tr);
l=tr;
r=ch[tr][1];
ch[tr][1]=0;
f[r]=0;
update(tr);
}
int merge(int x,int y){
int tr=find_k(x,Size[x]);
splay(tr);
ch[tr][1]=y;
f[y]=tr;
update(tr);
return tr;
}
void solve(int x){
if(x==0) return;
pushdown(x);
solve(ch[x][0]);
ans.push_back(val[x]);
solve(ch[x][1]);
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
rt=build(n+1);
while(m--){
int a,b;
scanf("%d%d",&a,&b);
int l,mid,r,o;
split(rt,a,l,o);
split(o,b-a+1,mid,r);
flip[mid]^=1;
rt=merge(merge(l,mid),r);
}
solve(rt);
for(int i=1;i<ans.size();i++){
if(i>1) printf(" ");
printf("%d",ans[i]-1);
}
puts("");
return 0;
}
UVA 11922
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 100005;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
typedef long long ll;
int l,r,sz,rt;
int f[maxn];
int ch[maxn][2];
int val[maxn];
int Size[maxn];
int flip[maxn];
vector<int> ans;
int get(int x){
return ch[f[x]][1]==x;
}
void update(int x){
if(x){
Size[x]=1;
if(ch[x][0]) Size[x]+=Size[ch[x][0]];
if(ch[x][1]) Size[x]+=Size[ch[x][1]];
}
}
void init(){
for(int i=0;i<=sz;i++){
ch[i][0]=ch[i][1]=Size[i]=flip[i]=0;
}
rt=sz=0;
}
void pushdown(int x){
if(flip[x]){
swap(ch[x][0],ch[x][1]);
flip[ch[x][0]]=!flip[ch[x][0]];
flip[ch[x][1]]=!flip[ch[x][1]];
flip[x]=0;
}
}
void rotate(int x){
int y=f[x];
int z=f[y];
int k = get(x);
ch[y][k]=ch[x][k^1]; f[ch[y][k]]=y;
f[y]=x;ch[x][k^1]=y;
f[x]=z;
if(z) ch[z][ch[z][1]==y]=x;
update(y);
update(x);
}
void splay(int x){
int y;
int z;
// pushdown(x);
while(y=f[x]){
// pushdown(y);
z=f[y];
if(z){
// pushdown(z);
if(get(x)==get(y)) rotate(y);
else rotate(x);
}
rotate(x);
}
rt=x;
}
void insert(int v){
if(rt==0){
sz++;
ch[sz][0]=ch[sz][1]=f[sz]=0;
val[sz]=v;Size[sz]=1;rt=sz;
return;
}
int x=rt;
while(true){
int y=ch[x][val[x]<v];
if(y==0){
sz++;
ch[sz][0]=ch[sz][1]=0;
val[sz]=v;Size[sz]=1;
f[sz]=x;ch[x][val[x]<v]=sz;
splay(sz);
break;
}
x=y;
}
}
int find_k(int tr,int x){
int now=tr;
while(true){
pushdown(now);
if(ch[now][0]&&x<=Size[ch[now][0]]){
now=ch[now][0];
}else {
int tmp=(ch[now][0]?Size[ch[now][0]]:0)+1;
if(x==tmp) return now;
x-=tmp;
now=ch[now][1];
}
}
}
int build(int len){
// cout<<"pre "<<len<<' '<<sz<<endl;
if(!len) return 0;
int l=build(len>>1);
int o = ++sz;
// cout<<len<<' '<<o<<endl;
val[o]=sz;
ch[o][0]=l;
ch[o][1]=build(len-(len>>1)-1);
f[ch[o][0]]=f[ch[o][1]]=o;
flip[o]=Size[o]=0;
update(o);
return o;
}
void split(int o,int k,int& l,int& r){
int tr = find_k(o,k);
// cout<<"split "<<tr<<' '<<val[tr]<<endl;
splay(tr);
l=tr;
r=ch[tr][1];
ch[tr][1]=0;
f[r]=0;
update(tr);
}
int merge(int x,int y){
int tr=find_k(x,Size[x]);
splay(tr);
ch[tr][1]=y;
f[y]=tr;
update(tr);
return tr;
}
void solve(int x){
// cout<<"solve "<<x<<endl;
if(x==0) return;
pushdown(x);
solve(ch[x][0]);
ans.push_back(val[x]);
solve(ch[x][1]);
}
void display(int x){
ans.clear();
solve(x);
for(int i=0;i<ans.size();i++){
cout<<ans[i]-1<<' ';
}
puts("");
}
int main(){
init();
int n,m;
scanf("%d%d",&n,&m);
rt=build(n+1);
// display(rt);
while(m--){
int a,b;
scanf("%d%d",&a,&b);
int l,mid,r,o;
split(rt,a,l,o);
// display(l);
// display(o);
split(o,b-a+1,mid,r);
// display(mid);
flip[mid]^=1;
rt==merge(merge(l,r),mid);
// display(rt);
}
solve(rt);
for(int i=1;i<ans.size();i++){
printf("%d\n",ans[i]-1);
}
return 0;
}