POI2011 Tree Rotations】的更多相关文章

2212: [Poi2011]Tree Rotations Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 391  Solved: 127[Submit][Status] Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists o…
线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子. #include<bits/stdc++.h> using namespace std; #define M(l, r) (((l) + (r)) >> 1) typedef long long ll; ; ; struct Node *null, *pt; struct Node { Node *l, *r; int cnt; Node() : cnt() { l = r = null; }…
2212: [Poi2011]Tree Rotations https://www.lydsy.com/JudgeOnline/problem.php?id=2212 分析: 线段树合并. 首先对每个节点建立一棵权值线段树,然后遍历整棵树,从叶子节点开始合并,每次合并两个节点的主席树,判断是否交换这两个节点,求出这两个节点分在前面所形成的逆序对. 求逆序对:对于主席树中的右子树一定比左子树大,所以每次合并一个节点时,直接用右子树的个数乘以左子树的个数,不断递归. 代码: #include<cst…
[BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists of straight branches, bifurcations and leaves. The trunk stemming from the gro…
POI2011 Tree Rotations 给定一个n<=2e5个叶子的二叉树,可以交换每个点的左右子树.要求前序遍历叶子的逆序对最少. 由于对于当前结点x,交换左右子树,对于范围之外的逆序对个数并没有影响,所以可以进行线段树合并,合并时统计l在左边还是在右边更优. #include <cstdio> #include <cctype> using namespace std; typedef long long LL; inline void read(int &…
Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists of straight branches, bifurcations and leaves. The trunk stemming from the ground is also a branch. Each branch…
原文地址:http://www.cnblogs.com/GXZlegend/p/6826614.html 题目描述 Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists of straight branches, bifurcations and leaves. The trunk stemming…
Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists of straight branches, bifurcations and leaves. The trunk stemming from the ground is also a branch. Each branch…
题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换左右子树无关,是否交换左右子树取决于交换后 “跨越 x 左子树与右子树的逆序对” 是否会减小. 因此我们要求出两种情况下的逆序对数,使用线段树合并,对每个节点建一棵线段树,然后合并的同时就求出两种情况下的逆序对. 代码 #include <iostream> #include <cstdli…
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2212 [题目大意] 给出一棵二叉树,每个叶节点上有一个权值,现在可以任意交换左右儿子, 使得逆序对最少,求最少的逆序对数量 [题解] 我们发现对于每个非叶节点来说,其贡献值为左右两个儿子的权值树上, 每个节点想反位置的数量和乘积,比如左儿子的权值树左节点和右儿子权值树的右节点相乘, 那么我们对于每个节点建立一颗权值线段树,仅保留非0链, 递归合并这些权值线段树,同时每次将相反位置数量…
题意 给一棵\(n(1 \le n \le 200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 分析 可以发现如果交换非叶结点的左右子树,对子树内的交换无影响,对子树外的交换也无影响,所以答案的贡献只是左子树与右子树之间是否交换得到的最小的逆序对数. 题解 考虑分治,对于一个点\(x\),我们只需要将其其中的一个子树的叶子插入到bit中,然后用另一个子树的叶子就能求得其逆序对数.那么发现一个点在遍历过程中可能插入的次数不只1次,对复杂度的影响主要就是重复插…
题目分析: 写的无旋treap应该跑不过,但bzoj判断的总时限.把相关实现改成线段树合并就可以了. 代码: #include<bits/stdc++.h> using namespace std; ; int n; ],num,val[maxn]; ][],sz[maxn],rot[maxn],data[maxn],key[maxn]; ; int merge(int r1,int r2){ ) ) return r1; if(key[r1] < key[r2]){ son[r1][]…
题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #include <cstring> #define Sqr(x) ((x)*(x)) using namespace std; const int N = 2e5 + 5; const int…
题解: 傻逼题 启发式合并线段树里面查$nlog^2$ 线段树合并顺便维护一下$nlogn$ 注意是叶子为n 总结点2n 代码: #include <bits/stdc++.h> using namespace std; #define rint register int #define IL inline #define rep(i,h,t) for(int i=h;i<=t;i++) #define dep(i,t,h) for(int i=t;i>=h;i--) #defin…
原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 题解 线段树合并. 博主很懒,题解不写了. 这份代码是仿照别人的写的. 代码 #include <cstring> #include <cstdio> #include <cmath> #include <al…
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换. 实现代码: #include<bits/stdc++.h> using namespace std; #define ll long long ; int n,cnt,idx; ll ans,cnt1,cnt2; int v[M],l[M],r[M],root[M]; ],ls[M*],rs[M*];…
题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少. \(Solution\) 很重要的一点是在子树内部交换左右儿子对其它子树是没有影响的.(当然更大区间内交换两棵子树对子树内部也是没有影响的) 所以DFS,对每个节点的两棵子树,如果换了更优就换,不优就不换. 怎么统计两棵子树换/不换产生的逆序对数呢,用两棵子树的值域线段树合并解决.换/不换产生的逆序对数根…
题目链接 BZOJ2212 题解 一棵子树内的顺序不影响其与其它子树合并时的答案,这一点与归并排序的思想非常相似 所以我们只需单独处理每个节点的两棵子树所产生的最少逆序对即可 只有两种情况,要么正序要么逆序,且这两种情况数目是互补的 如果左子树大小为\(S_l\),右子树大小为\(S_r\),那么总对数为\(S_lS_r\) 如何快速统计一棵子树中大于另一棵子树中权值的对数? 开一个权值线段树,在线段树合并过程中统计即可 由于权值是一个排列,所以复杂度是\(O(nlogn)\) 顺带一提,左右儿…
题目链接 通过观察与思考,我们可以发现,交换一个结点的两棵子树,只对这两棵子树内的节点的逆序对个数有影响,对这两棵子树以外的节点是没有影响的.嗯,然后呢?(っ•̀ω•́)っ 然后,我们就可以对于每一个节点的两棵子树,求出其交换前与交换后的两棵子树内的逆序对个数,取最小就好啦! 怎么求啊,不能暴力吧,TLE啊,不会了呀!!! (ノ`⊿´)ノ(掀桌 对了,我们有线段树合并!(o゚▽゚)o (如果不知道线段树合并是什么可以看这一篇文章哦.) 对于每一个叶节点,我们都可以建一棵权值线段树,然后一步一步合…
BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some interesting features: The tree consists of straight branches, bifurcations and leaves. The trunk stemming from t…
P3521 [POI2011]ROT-Tree Rotations 题意: 给你一颗树,只有叶子节点有权值,你可以交换一个点的左右子树,问你最小的逆序对数 题解: 线段树维护权值个个数即可 然后左右子树合并时计算交换和不交换的贡献取一个min即可 代码: /** * ┏┓ ┏┓ * ┏┛┗━━━━━━━┛┗━━━┓ * ┃ ┃ * ┃ ━ ┃ * ┃ > < ┃ * ┃ ┃ * ┃... ⌒ ... ┃ * ┃ ┃ * ┗━┓ ┏━┛ * ┃ ┃ Code is far away from b…
题目[POI2011]ROT-Tree Rotations [Description] 现在有一棵二叉树,所有非叶子节点都有两个孩子.在每个叶子节点上有一个权值(有\(n\)个叶子节点,满足这些权值为\(1..n\)的一个排列).可以任意交换每个非叶子节点的左右孩子. 要求进行一系列交换,使得最终所有叶子节点的权值按照中序遍历写出来,逆序对个数最少. [Input Format] 第一行一个整数\(n\). 下面每行,一个数\(x\). 如果\(x =0\),表示这个节点非叶子节点,递归地向下读…
P3521 [POI2011]ROT-Tree Rotations loj2163 [POI2011]ROT-Tree Rotations(数据加强) (loj的数据套了个fread优化才过...) 显然地,对于一棵线段树(树根设为$rt$),是否翻转它的子树的子树,对于跨$mid$的逆序对数量没有影响. 那么我们可以层层统计(设左右子树为$lc,rc$): 不翻转时,该层(跨$mid$)的逆序对:$a[a[a[rt].lc].rc].sum*a[a[a[rt].rc].lc].sum$ 翻转时…
bzoj 2212 Tree Rotations 考虑一个子树 \(x\) 的左右儿子分别为 \(ls,rs\) .那么子树 \(x\) 内的逆序对数就是 \(ls\) 内的逆序对数,\(rs\) 内的逆序对数,跨越 \(ls,rs\) 的逆序对数三者之和. 交换 \(ls,rs\) 显然对前两种的答案没有影响,只需最大化最后一种答案. 对每个叶子节点开一棵权值线段树向上合并,选取权值中点 \(mid\) 划分开,那么两种情况在当前层产生的贡献即为 \(ls\) 的左子树大小 \(\times\…
P3521 [POI2011]ROT-Tree Rotations 题意:递归给出给一棵\(n(1≤n≤200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 大体给出方式: 第一行一个正整数\(n\),表示该二叉树的叶节点的个数: 下面若干行,每行一个数\(p\): 如果\(p=0\),表示这个节点不是叶节点,递归地向下读入其左孩子和右孩子的信息: 如果\(p \neq 0\) ,表示这个节点是叶节点,权值为\(p\) . 本来想学一下启发式合并的,结果被一…
P3521 [POI2011]ROT-Tree Rotations 题目大意: 给一棵\((1≤n≤200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 我们发现交换两个子树并不会影响某个子树内的逆序对个数,只会对两个子树之间的逆序对产生影响. 所以我们将换与不换的逆序对求出来,取个最小值 将两颗线段树合并就好了 #include<cstdio> #include<cstring> #include<iostream> #inclu…
题目链接 [BZOJ] [洛谷] [LOJ] 题解 由于是前序遍历,那么讨论一棵树上的逆序对的情况. 两个节点都在左子树上 两个节点都在右子树上 两个节点分别在不同的子树上. 前两种情况其实也可以归结于第三种情况. 原因 因为两个节点不可能占据一个位置. 根据容斥原理,为了保证答案的正确性,我们递归求解不能计算两遍相同的答案. 回到正题 所以我们只需要讨论跨越两个子树的情况. 很显然,左子树中的所有点的\(dfs\)序都比右子树的子树中的小. 那么如果要交换,就是相反一下. 比较容易可以想到对于…
这道题采用权值线段树合并的解法. 首先讲一下解法中出现的两个概念:权值线段树与线段树合并. 所谓权值线段树,可以理解为维护的信息反过来的普通线段树,我个人认为值域线段树这个名字其实要准确一些. 举个例子,我们将序列$1,1,2,3,4,4,4,5,6,6$中的数依次插入,那么插入完成之后的效果图大概是下面这样的: (其中红色为节点的值) 也就是说,每一个节点维护的值是这个区间内的数出现的次数. 在实现权值线段树时,我们通常会采用动态开点的方式,也就是不创建无关的节点,当然也可以离散化数据,否则必…
一句话题意(不用我改了.....):给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. ......这题输入很神烦呐... 给你一棵二叉树的dfs序(考场上没发现2333),只有叶子结点有值,然后求逆序对大小 在考场上,建树建了好久,然后暴力暴了好久,然后得到了0分的好成绩呢(我真棒) 正解其实也不难想(但是当时不会权值线段树) 题解: 其实很简单,想想:对于一层的逆序对,数量是一定的.也就是说,无论怎么转当前子树,对上一层的逆序对数量是没有影…
题面 这道题咋看都是无法从dp入手,那么就从数据结构入手!: 首先你要会权值线段树和线段树合并. 然后你要知道: 对于任意一个节点,交换左右子树对当前节点和前面的所有节点没有影响. 因为这是前序遍历:根节点->左子树->右子树.可以看到,交换左右子树对前面的节点无影响. 我们清楚,交换子树只会对该逆序对横跨左右子树这种情况产生影响.因此,我们只需要在合并线段树的过程中统计交换子树的逆序对个数ans1和不交换子树的逆序对个数ans1,取 min(ans1,ans2) 累加到答案中就行了. 每一次…