这棵漂亮的平衡树写挂了。
如果将整棵树都 pushdown 一遍可以过样例,但是只pushdown 特定节点(根节点)无法通过。
蒟蒻求教,不胜感激。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
struct node{
int s[2],p,size;
int v,id;
int tag;
}sp[maxn];
int rt,idx,to[maxn];
int n,m;
pair<int,int>b[maxn];
bool cmp(pair<int,int> u,pair<int,int> v){
return u.second==v.second?u.first<v.first:u.second<v.second;
}
void pushup(int x){
sp[x].size=sp[sp[x].s[0]].size+sp[sp[x].s[1]].size+1;
}
void pushdown(int x){
if(sp[x].tag){
swap(sp[x].s[0],sp[x].s[1]);
sp[sp[x].s[0]].tag^=1;
sp[sp[x].s[1]].tag^=1;
sp[x].tag=0;
}
}
void rotate(int x){
int y=sp[x].p,z=sp[y].p;
int k=sp[y].s[1]==x;
sp[z].s[sp[z].s[1]==y]=x,sp[x].p=z;
sp[y].s[k]=sp[x].s[k^1],sp[sp[x].s[k^1]].p=y;
sp[x].s[k^1]=y,sp[y].p=x;
pushup(y),pushup(x);
}
void splay(int x,int k){
while(sp[x].p!=k){
int y=sp[x].p,z=sp[y].p;
if(z!=k){
if((sp[y].s[1]==x)^(sp[z].s[1]==y))
rotate(x);
else rotate(y);
}
rotate(x);
}
if(!k)rt=x;
}
void insert(int v,int id){
int u=rt,p=0;
while(u)
p=u,u=sp[u].s[v>sp[u].v];
u=++idx;
if(p)sp[p].s[v>sp[p].v]=u;
sp[u].v=v,sp[u].p=p;
sp[u].size=1,sp[u].id=id;
if(id>0)to[id]=idx;
splay(u,0);
}
int get_k(int u,int k){
pushdown(u);
if(sp[sp[u].s[0]].size>=k)
return get_k(sp[u].s[0],k);
if(sp[sp[u].s[0]].size+1==k)return u;
return get_k(sp[u].s[1],k-sp[sp[u].s[0]].size-1);
}
int get_k(int k){return get_k(rt,k);}
int ne(int u){
pushdown(u);
u=sp[u].s[1];
while(1){
pushdown(u);
if(sp[u].s[0])u=sp[u].s[0];
else break;
}
return u;
}
void output(int u){
pushdown(u);
if(sp[u].s[0])output(sp[u].s[0]);
if(1<=sp[u].v&&sp[u].v<=n)cout<<sp[u].id<<' ';
if(sp[u].s[1])output(sp[u].s[1]);
}
int main(){
cin>>n;
insert(0,-1);
for(int i=1,t;i<=n;i++)
cin>>t,b[i]={i,t};
sort(b+1,b+n+1,cmp);
for(int i=1;i<=n;i++)
insert(b[i].first,b[i].second);
insert(n+1,-1);
for(int i=1,l,r;i<=n;i++){
splay(to[i],0);
pushdown(to[i]);
pushdown(sp[to[i]].s[0]);
cout<<sp[sp[to[i]].s[0]].size<<' ';
l=get_k(i),r=ne(to[i]);
splay(l,0),splay(r,l);
sp[sp[r].s[0]].tag^=1;
}
}