BZOJ 2212: [Poi2011]Tree Rotations 线段树合并

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; 
}

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/12111918.html