• BZOJ2212 [Poi2011]Tree Rotations 【线段树合并】


    题目链接

    BZOJ2212

    题解

    一棵子树内的顺序不影响其与其它子树合并时的答案,这一点与归并排序的思想非常相似
    所以我们只需单独处理每个节点的两棵子树所产生的最少逆序对即可
    只有两种情况,要么正序要么逆序,且这两种情况数目是互补的
    如果左子树大小为(S_l),右子树大小为(S_r),那么总对数为(S_lS_r)

    如何快速统计一棵子树中大于另一棵子树中权值的对数?
    开一个权值线段树,在线段树合并过程中统计即可
    由于权值是一个排列,所以复杂度是(O(nlogn))

    顺带一提,左右儿子都满的二叉树节点数(n = 2s - 1)(s)表示叶子的个数
    可以用数归证明
    所以节点数最多不超过(4 imes 10^5)

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    using namespace std;
    const int maxn = 400005,maxm = 10000005,INF = 1000000000;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
    	return out * flag;
    }
    int n,N,rt[maxn],sum[maxm],ls[maxm],rs[maxm],cnt;
    LL ans,tot;
    void modify(int& u,int pre,int l,int r,int pos){
    	sum[u = ++cnt] = sum[pre] + 1;
    	ls[u] = ls[pre]; rs[u] = rs[pre];
    	if (l == r) return;
    	int mid = l + r >> 1;
    	if (mid >= pos) modify(ls[u],ls[pre],l,mid,pos);
    	else modify(rs[u],rs[pre],mid + 1,r,pos);
    }
    int merge(int u,int v){
    	if (!u) return v;
    	if (!v) return u;
    	int t = ++cnt;
    	sum[t] = sum[u] + sum[v];
    	tot += 1ll * sum[rs[u]] * sum[ls[v]];
    	ls[t] = merge(ls[u],ls[v]);
    	rs[t] = merge(rs[u],rs[v]);
    	return t;
    }
    int dfs(){
    	int x = read(); int u = ++N;
    	if (x){
    		modify(rt[u],rt[u],1,n,x);
    		return u;
    	}
    	int L = dfs(),R = dfs(); LL S = 1ll * sum[rt[L]] * sum[rt[R]];
    	tot = 0;
    	rt[u] = merge(rt[L],rt[R]);
    	ans += min(tot,S - tot);
    	return u;
    }
    int main(){
    	n = read();
    	dfs();
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Roofline Model与深度学习模型的性能分析
    卷积神经网络的复杂度分析
    CNN中卷积层的计算细节
    ImageNet 历届冠军最新评析:哪个深度学习模型最适合你?
    最新ICE源码编译安装
    CNN 模型压缩与加速算法综述
    YAML 与 front-matter
    VMware 虚拟机快照、克隆、磁盘扩容
    ubuntu16.04安装Nvidia显卡驱动、CUDA8.0和cudNN V6
    宏使用 Tricks
  • 原文地址:https://www.cnblogs.com/Mychael/p/9205459.html
Copyright © 2020-2023  润新知