线段树合并

BZOJ2212

#include <cstdio>
#include <iostream>
#define LL long long 
using namespace std;

  int cnt,n;
  LL tmp,tot,ans;

  struct treenode{
     LL size,lc,rc;
  }tr[4000001];

  int newnode(int l,int r,int tar){
      tr[++cnt].size=1;
      if (l==r) return(cnt);
      int mid=(l+r)>>1,t=cnt;
      if (tar<=mid) tr[t].lc=newnode(l,mid,tar);else tr[t].rc=newnode(mid+1,r,tar);
      return(t);
  }
  
  int merge(int poa,int pob,int l,int r){
    if (poa==0) return(pob);
    if (pob==0) return(poa);
    tr[poa].size+=tr[pob].size;
    if (l==r) return(poa);
    
    tmp+=tr[tr[poa].lc].size*tr[tr[pob].rc].size;
    int mid=(l+r)>>1,t=poa;
    tr[poa].lc=merge(tr[poa].lc,tr[pob].lc,l,mid);
    tr[poa].rc=merge(tr[poa].rc,tr[pob].rc,mid+1,r);
    return(poa);
  }

  int work(){
      int t;
      scanf("%d",&t);
      if (t!=0){return(newnode(1,n,t));}else{
        int t1=work(),t2=work();
      tot=tr[t1].size*tr[t2].size,tmp=0;
      int ret=merge(t1,t2,1,n);    
      ans+=min(tmp,tot-tmp);
      return(ret);
    }
  }

  int main(){      
      scanf("%d",&n);
      work();
      printf("%lld
",ans);
  }
原文地址:https://www.cnblogs.com/zhujiangning/p/6294090.html