code:
#include <cstdio> #include <string> #include <algorithm> #define N 200007 #define ll long long using namespace std; namespace IO { void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); // freopen(out.c_str(),"w",stdout); } }; int n,tot; int rt[N<<1]; ll ans1,ans2,ans; struct node { int val,ls,rs; }t[N*40]; void update(int &x,int l,int r,int p) { if(!x) x=++tot; ++t[x].val; if(l==r) return; int mid=(l+r)>>1; if(p<=mid) update(t[x].ls,l,mid,p); else update(t[x].rs,mid+1,r,p); } int merge(int x,int y) { if(!x||!y) return x+y; int now=++tot; t[now].val=t[x].val+t[y].val; // t[x].val+=t[y].val; ans1+=(ll)t[t[x].rs].val*t[t[y].ls].val; ans2+=(ll)t[t[y].rs].val*t[t[x].ls].val; t[now].ls=merge(t[x].ls,t[y].ls); t[now].rs=merge(t[x].rs,t[y].rs); return now; } int build() { int x; scanf("%d",&x); if(!x) { int lson=build(); int rson=build(); ans1=ans2=0; rt[x]=merge(lson,rson); ans+=min(ans1,ans2); } else update(rt[x],1,n,x); return rt[x]; } int main() { // IO::setIO("input"); int i,j; scanf("%d",&n); build(); printf("%lld\n",ans); return 0; }
BZOJ 2212: [Poi2011]Tree Rotations 线段树合并
原文:https://www.cnblogs.com/guangheli/p/12111918.html