zoukankan      html  css  js  c++  java
  • P3521 [POI2011]ROT-Tree Rotations

    传送门

    权值线段树+线段树合并

    我们对每一个节点开一棵权值线段树,那么考虑一个节点是否交换它的左右儿子。首先交换对左右子树内部的逆序对数无影响,对该子树与子树之外的逆序对也没有影响,于是只要考虑左右子树的逆序对数即可。考虑当前为权值线段树上的节点,(x,y)分别是左右子树上得到该节点,(L,R,sum)分别为线段树左右儿子以及该节点的数的个数,那么如果不交换,逆序对个数是(sum[R[x]]*sum[L[y]]),如果交换,那么逆序对个数是(sum[L[x]]*sum[R[y]]),那么只要我们在线段树合并的过程中把两个答案都统计出来,最后加上小的那一个就行了

    说的可能有点不清楚,代码应该会比较好理解

    另外这题的读入非常的迷……

    第一行一个正整数$n$,表示该二叉树的叶节点的个数;
    
    下面若干行,每行一个数$x$:
    
    如果$x = 0$,表示这个节点不是叶节点,递归地向下读入其左孩子和右孩子的信息;
    
    如果$x 
    eq 0$,表示这个节点是叶节点,权值为$x$。
    
    //minamoto
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
    char buf[1<<21],*p1=buf,*p2=buf;
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    int read(){
        int res,f=1;char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=2e5+5;
    int n,tot,L[N*20],R[N*20],val[N*20],tmp;ll ans,ans1,ans2;
    void upd(int &p,int l,int r,int x){
    	if(!p)p=++tot;++val[p];if(l==r)return;
    	int mid=(l+r)>>1;
    	x<=mid?upd(L[p],l,mid,x):upd(R[p],mid+1,r,x);
    }
    void merge(int &x,int y){
    	if(!x||!y)return (void)(x+=y);
    	val[x]+=val[y];
    	ans1+=1ll*val[L[x]]*val[R[y]],ans2+=1ll*val[R[x]]*val[L[y]];
    	merge(R[x],R[y]),merge(L[x],L[y]);
    }
    void dfs(int &x){
    	int tmp=read(),ls,rs;x=0;
    	if(!tmp){
    		dfs(ls),dfs(rs),ans1=ans2=0;
    		x=ls,merge(x,rs),ans+=min(ans1,ans2);
    	}else upd(x,1,n,tmp);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),dfs(tmp),printf("%lld
    ",ans);return 0;
    }
    
  • 相关阅读:
    array and ram
    char as int
    pointer of 2d array and address
    Install SAP HANA EXPRESS on Google Cloud Platform
    Ubuntu remount hard drive
    Compile OpenSSL with Visual Studio 2019
    Install Jupyter notebook and tensorflow on Ubuntu 18.04
    Build OpenCV text(OCR) module on windows with Visual Studio 2019
    Reinstall VirtualBox 6.0 on Ubuntu 18.04
    Pitfall in std::vector<cv::Mat>
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9968700.html
Copyright © 2011-2022 走看看