解题思路
支持区间翻转。
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<cstdlib>
using namespace std;
int n;
struct ldx{
int x,wi;
bool operator < (const ldx p) const{
return x<p.x || x==p.x && wi<p.wi;
}
}ap[100005];
struct node{
int siz,key;
bool rev_mark;
node* ch[2],*fa;
node();
void rev();
void pushdown();
void maintain();
int son(){
if(fa->ch[0]==this) return 0;
if(fa->ch[1]==this) return 1;
return -1;
}
}*null=new node(),*s[100005],*root;
node:: node(){
siz=null ? 1 : 0;rev_mark=0;
ch[0]=ch[1]=fa=null;
}
void node:: rev(){
if(this==null) return ;
swap(ch[0],ch[1]);
rev_mark^=1;
}
void node:: pushdown(){
if(!rev_mark) return ;
rev_mark^=1;
ch[0]->rev();ch[1]->rev();
}
void node:: maintain() {siz=ch[0]->siz+ch[1]->siz+1;}
void Rotate(node* p,bool f){
node* t=p->ch[f^1];
p->ch[f^1]=t->ch[f];
if(t->ch[f]!=null) t->ch[f]->fa=p;
t->ch[f]=p;
p->maintain();t->maintain();
if(~p->son()) p->fa->ch[p->son()]=t;
t->fa=p->fa;p->fa=t;
}
void To_pushdown(node* p){
if(p!=root) To_pushdown(p->fa);
p->pushdown();
}
void splay(node* p,bool f){
if(!f){
while(~p->son()){
int dir=p->son();
if(p->fa->son()==dir) Rotate(p->fa->fa,dir^1);
Rotate(p->fa,dir^1);
}
root=p;
}
else {
while(~p->son()){
int dir=p->son();
if(p->fa==root) return ;
if(p->fa->fa==root) {Rotate(p->fa,dir^1);return ;}
if(p->fa->son()==dir) Rotate(p->fa->fa,dir^1);
Rotate(p->fa,dir^1);
}
}
}
node* kth(node* p,int x){
p->pushdown();
int sum=p->ch[0]->siz+1;
if(sum==x) return p;
else if(sum>x) return kth(p->ch[0],x);
else return kth(p->ch[1],x-sum);
}
void build(node* &p,int x,int y){
if(x>y) return ;
int mid=x+y>>1;p=new node();p->key=ap[mid].x;
build(p->ch[0],x,mid-1);build(p->ch[1],mid+1,y);
if(p->ch[0]!=null) p->ch[0]->fa=p;
if(p->ch[1]!=null) p->ch[1]->fa=p;
p->maintain();
}
void sett(){
null->ch[0]=null->ch[1]=null->fa=null;
root=new node();root->ch[1]=new node();root->ch[1]->fa=root;
build(root->ch[1]->ch[0],1,n);root->ch[1]->ch[0]->fa=root->ch[1];
root->ch[1]->maintain();root->maintain();
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) {scanf("%d",&ap[i].x);ap[i].wi=i;}
sett();sort(ap+1,ap+n+1);
for(int i=1;i<=n;i++) s[i]=kth(root,ap[i].wi+1);
for(int i=1;i<=n;i++){
To_pushdown(s[i]);splay(s[i],0);
if(i!=n) printf("%d ",root->ch[0]->siz);
else printf("%d",root->ch[0]->siz);
int k1=root->ch[0]->siz,k2=i;
if(k1==k2) continue;
if(k1>k2) swap(k1,k2);
node* r1=kth(root,k1);splay(r1,0);
node* r2=kth(root,k2+2);splay(r2,1);
root->ch[1]->ch[0]->rev();
}
return 0;
}