RT,写的Dsu On Tree+BIT,T了两个,同样的题解效率优秀,不知道是哪里写假了
#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
x=0;bool f=false;char ch=getchar();
while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return ;
}
template <typename T>
inline void write(T x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10^48);
return ;
}
const int N=2e5+5;
int n,tot,root,val[N],ls[N],rs[N],siz[N],son[N];
int c[N],ans,top,sta[N];
void Add(int x,int v){
for(;x<=n;x+=(x&(-x))) c[x]+=v;
return ;
}
int Query(int x){
int res=0;
for(;x;x-=(x&(-x))) res+=c[x];
return res;
}
int DFS(){
int k;int now=++tot;
read(k);val[now]=k;
if(!k) ls[now]=DFS();
if(!k) rs[now]=DFS();
return now;
}
void Dfs1(int x){
if(!x) return ;
Dfs1(ls[x]);
Dfs1(rs[x]);
if(siz[ls[x]]>siz[rs[x]]) son[x]=ls[x];
else son[x]=rs[x];
siz[x]=siz[ls[x]]+siz[rs[x]]+1;
return ;
}
void Push(int x){
if(!x) return ;
if(val[x]){sta[++top]=val[x];return ;}
Push(ls[x]);
Push(rs[x]);
return ;
}
void Delete(int x){
top=0;Push(x);
for(int i=1;i<=top;i++) Add(sta[i],-1);
return ;
}
void Dsu_On_Tree(int x,int tag){
if(!x) return ;
if(val[x]){if(tag){Add(val[x],1);};return ;}
if(son[x]==ls[x]){
Dsu_On_Tree(rs[x],0);
Dsu_On_Tree(ls[x],1);
int ans1=0,ans2=0;top=0;
Push(rs[x]);
int q=Query(n);
for(int i=1;i<=top;i++) ans1+=q-Query(sta[i]),ans2+=Query(sta[i]-1);
ans+=min(ans1,ans2); top=0;
Push(rs[x]);
for(int i=1;i<=top;i++) Add(sta[i],1);
if(!tag) Delete(x);
}
else{
Dsu_On_Tree(ls[x],0);
Dsu_On_Tree(rs[x],1);
int ans1=0,ans2=0;top=0;
Push(ls[x]);
int q=Query(n);
for(int i=1;i<=top;i++) ans1+=q-Query(sta[i]),ans2+=Query(sta[i]-1);
ans+=min(ans1,ans2); top=0;
Push(ls[x]);
for(int i=1;i<=top;i++) Add(sta[i],1);
if(!tag) Delete(x);
}
return ;
}
signed main(){
read(n);
root=DFS();
Dfs1(root);
Dsu_On_Tree(root,1);
write(ans);
return 0;
}