题目链接:https://www.luogu.org/problem/P3391
思路:splay模板题
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <unordered_map>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define pb push_back
#define eps 1e-7
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
const int N = 100005;
struct node{
int ch[2],fa,val,sz,cnt;
bool rev;
void init(int x,int ff)
{
ch[0]=ch[1]=0;
cnt=sz=1;val=x;fa=ff;
}
}tr[N+1];
int root,ncnt;
int n,m,x,y;
bool chk(int x) {return tr[tr[x].fa].ch[1]==x;}
void pushup(int x) {tr[x].sz=tr[tr[x].ch[0]].sz+tr[tr[x].ch[1]].sz+tr[x].cnt;}
void pushdown(int x)//标记
{
if(tr[x].rev)
{
swap(tr[x].ch[0],tr[x].ch[1]);
tr[tr[x].ch[0]].rev^=1;
tr[tr[x].ch[1]].rev^=1;
tr[x].rev=0;
}
}
void rot(int x)//旋转
{
int y=tr[x].fa,z=tr[y].fa,k=chk(x),w=tr[x].ch[k^1];
tr[y].ch[k]=w;tr[w].fa=y;
tr[z].ch[chk(y)]=x;tr[x].fa=z;
tr[x].ch[k^1]=y;tr[y].fa=x;
pushup(y);pushup(x);
}
void splay(int x, int goal = 0)//伸展
{
while(tr[x].fa!=goal)
{
int y=tr[x].fa,z=tr[y].fa;
if(z!=goal)
chk(x)^chk(y)?rot(x):rot(y);
rot(x);
}
if(!goal) root=x;
}
void add(int x)//加点
{
int cur=root,p=0;
while(cur&&tr[cur].val!=x)
{
p=cur;
cur=tr[cur].ch[x>tr[cur].val];
}
if(cur) tr[cur].cnt++;
else
{
cur=++ncnt;
if(p) tr[p].ch[x>tr[p].val]=cur;
tr[cur].init(x,p);
}
splay(cur);
}
void fid(int x)
{
int cur=root;
while(tr[cur].ch[x>tr[cur].val]&&tr[cur].val!=x)
cur=tr[cur].ch[x>tr[cur].val];
splay(cur);
}
int kth(int k)//第几大
{
int cur=root;
while(666)
{
pushdown(cur);
if(tr[cur].ch[0]&&k<=tr[tr[cur].ch[0]].sz) cur=tr[cur].ch[0];
else if(k>tr[tr[cur].ch[0]].sz+tr[cur].cnt)
{
k-=tr[tr[cur].ch[0]].sz+tr[cur].cnt;
cur=tr[cur].ch[1];
}
else return cur;
}
}
void rever(int l,int r)//区间翻转
{
int x=kth(l),y=kth(r+2);
splay(x); splay(y,x);
tr[tr[y].ch[0]].rev^=1;
}
int pre(int x)//前驱
{
fid(x);
if(tr[root].val<x) return root;
int cur=tr[root].ch[0];
while(tr[cur].ch[1]) cur=tr[cur].ch[1];
return cur;
}
int succ(int x)//后继
{
fid(x);
if(tr[root].val>x) return root;
int cur=tr[root].ch[1];
while(tr[cur].ch[0]) cur=tr[cur].ch[0];
return cur;
}
void remov(int x)//删点
{
int last=pre(x),next=succ(x);
splay(last);splay(next,last);
int del=tr[next].ch[0];
if(tr[del].cnt>1) tr[del].cnt--,splay(del);
else tr[next].ch[0]=0;
pushup(next),pushup(root);
}
void output(int x)//输出遍历
{
pushdown(x);
if(tr[x].ch[0]) output(tr[x].ch[0]);
if(tr[x].val&&tr[x].val<=n) printf("%d ",tr[x].val);
if(tr[x].ch[1]) output(tr[x].ch[1]);
}
inline int read()
{
int X=0,w=0; char ch=0;
while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
return w?-X:X;
}
int main()
{
cin.tie(0);
cout.tie(0);
cin>>n>>m;
FOR(i,0,n+1) add(i);
while(m--)
{
x=read(),y=read();
rever(x,y);
}
output(root);
return 0;
}
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll inff = 0x3f3f3f3f3f3f3f3f;
#define FOR(i,a,b) for(int i(a);i<=(b);++i)
#define FOL(i,a,b) for(int i(a);i>=(b);--i)
#define REW(a,b) memset(a,b,sizeof(a))
#define inf int(0x3f3f3f3f)
#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define ss(a) scanf("%s",a)
#define pb push_back
#define eps 1e-7
#define lc d<<1
#define rc d<<1|1
#define Pll pair<ll,ll>
#define P pair<int,int>
#define pi acos(-1)
const int N = 200005;
struct node{
int ch[2],fa,val,sz,cnt,sd;
bool rev;
void init(int x,int ff,int y)
{
ch[0]=ch[1]=rev=0;sd=y;
cnt=sz=1;val=x;fa=ff;
}
}tr[N+1];
P b[N];
stack<int>st;
int root,ncnt;
int n,m,x,y;
bool chk(int x) {return tr[tr[x].fa].ch[1]==x;}
void pushup(int x) {tr[x].sz=tr[tr[x].ch[0]].sz+tr[tr[x].ch[1]].sz+tr[x].cnt;}
void pushdown(int x)//标记
{
if(tr[x].rev)
{
swap(tr[x].ch[0],tr[x].ch[1]);
tr[tr[x].ch[0]].rev^=1;
tr[tr[x].ch[1]].rev^=1;
tr[x].rev=0;
}
}
void rot(int x)//旋转
{
int y=tr[x].fa,z=tr[y].fa;
int k=chk(x),w=tr[x].ch[k^1];
tr[y].ch[k]=w;tr[w].fa=y;
tr[z].ch[chk(y)]=x;tr[x].fa=z;
tr[x].ch[k^1]=y;tr[y].fa=x;
pushup(y);pushup(x);
}
void splay(int x,int goal=0)//伸展
{
for(int qw=x;qw!=goal;qw=tr[qw].fa) st.push(qw);
while(!st.empty()) pushdown(st.top()),st.pop();
while(tr[x].fa!=goal)
{
int y=tr[x].fa,z=tr[y].fa;
if(z!=goal)
chk(x)^chk(y)?rot(x):rot(y);
rot(x);
}
if(!goal) root=x;
}
void add(int x,int y)//加点
{
int cur=root,p=0;
while(cur&&tr[cur].val!=x)
{
p=cur;
cur=tr[cur].ch[x>tr[cur].val];
}
if(cur) tr[cur].cnt++;
else
{
cur=++ncnt;
if(p) tr[p].ch[x>tr[p].val]=cur;
tr[cur].init(x,p,y);
}
splay(cur);
}
void rever(int x)//区间翻转
{
splay(x);
tr[tr[x].ch[0]].rev^=1;
}
void remov()//删点
{
int z=tr[root].ch[0];
if(!z)
{
root=tr[root].ch[1];
tr[root].fa=0;
return;
}
while(233)
{
pushdown(z);
if(!tr[z].ch[1]) break;
z=tr[z].ch[1];
}
splay(z,root);
tr[z].ch[1]=tr[root].ch[1];
tr[tr[root].ch[1]].fa=z;
root=z,tr[z].fa=0;
pushup(z);
}
int main()
{
cin.tie(0);
cout.tie(0);
while(si(n)!=EOF&&n)
{
root=ncnt=tr[0].ch[0]=tr[0].ch[1]=tr[0].cnt=tr[0].fa=tr[0].rev=tr[0].sd=tr[0].sz=tr[0].val=0;
add(inf,0);
FOR(i,1,n) si(x),add(i,x),b[i].first=x,b[i].second=i;
sort(b+1,b+n+1);
FOR(i,1,n)
{
x=b[i].second;
rever(x+1);
if(i!=n) printf("%d ",i+tr[tr[root].ch[0]].sz);
else printf("%d\n",i+tr[tr[root].ch[0]].sz);
remov();
}
}
return 0;
}