线段树合并(【POI2011】ROT-Tree Rotations)
线段树合并(【POI2011】ROT-Tree Rotations)
题意
现在有一棵二叉树,所有非叶子节点都有两个孩子。在每个叶子节点上有一个权值(有nn个叶子节点,满足这些权值为1…n1…n的一个排列)。可以任意交换每个非叶子节点的左右孩子。
要求进行一系列交换,使得最终所有叶子节点的权值按照前序遍历序写出来,逆序对个数最少。
解法
我们对每一个叶子节点建立一颗权值线段树,然后,我们考虑将两个叶子节点上的线段树合并起来,然后我们考虑逆序对的个数。
如果我们将左儿子的线段树放在前面,则产生的逆序对数为左儿子右边的sum * 右儿子左边的sum,反之同理。然后我们每次合并求出这两个之中的最小值加入ans中就好了。
代码
令我感到神奇的是,如果我们将dfs中的两句判断放在外面,常数为原来的3倍,如果不开O2就会TLE。
~~ 可我明明打的跟别人一样的代码,别人不开O2都只要300ms。自带常数型选手的悲哀。╮(╯﹏╰)╭ ~~
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>
#define INF 2139062143
#define MAX 0x7ffffffffffffff
#define del(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
template<typename T>
inline void read(T&x)
{
x=0;T k=1;char c=getchar();
while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
}
const int maxn=8000000+5;
struct node{
int lc,rc,sum;
node(int lc=0,int rc=0,int sum=0):lc(lc),rc(rc),sum(sum){}
}T[maxn*4];
int root[maxn];
int a[maxn];
int sz;
ll ans1,ans2;
void build(int x){
read(a[x]);
if(a[x]) return;
T[x].lc=++sz;build(T[x].lc);
T[x].rc=++sz;build(T[x].rc);
}
void updata(int l,int r,int pos,int val,int &x){
if(!x) x=++sz;
T[x].sum+=val;
if(l==r) return;
int mid=(l+r)/2;
if(pos<=mid) updata(l,mid,pos,val,T[x].lc);
else updata(mid+1,r,pos,val,T[x].rc);
}
int Merge(int x,int y){
if(!x||!y) return x+y;
ans1+=1ll*T[T[x].lc].sum*T[T[y].rc].sum;
ans2+=1ll*T[T[x].rc].sum*T[T[y].lc].sum;
T[x].lc=Merge(T[x].lc,T[y].lc);
T[x].rc=Merge(T[x].rc,T[y].rc);
T[x].sum=T[T[x].lc].sum+T[T[x].rc].sum;
return x;
}
ll ans=0;
void dfs(int x){
//若为叶子结点,往下递归会TLE???
if(!a[x]){
if(T[x].lc) dfs(T[x].lc);
if(T[x].rc) dfs(T[x].rc);
ans1=0;ans2=0;
root[x]=Merge(root[T[x].lc],root[T[x].rc]);
ans+=1ll*min(ans1,ans2);
}
}
int n;
int main()
{
read(n);
build(sz=1);
for(int i=1;i<=sz;i++)
if(a[i])
updata(1,n,a[i],1,root[i]);
dfs(1);
printf("%lld\n",ans);
return 0;
}
线段树合并(【POI2011】ROT-Tree Rotations)的更多相关文章
- bzoj3307雨天的尾巴(权值线段树合并/DSU on tree)
题目大意: 一颗树,想要在树链上添加同一物品,问最后每个点上哪个物品最多. 解题思路: 1.线段树合并 假如说物品数量少到可以暴力添加,且树点极少,我们怎么做. 首先在一个树节点上标记出哪些物品有多少 ...
- CF600E Lomsat gelral——线段树合并/dsu on tree
题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...
- 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并
[BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...
- 【bzoj2212】[Poi2011]Tree Rotations 权值线段树合并
原文地址:http://www.cnblogs.com/GXZlegend/p/6826614.html 题目描述 Byteasar the gardener is growing a rare tr ...
- [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】
题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...
- bzoj2212[Poi2011]Tree Rotations [线段树合并]
题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...
- 【BZOJ2212】[POI2011]Tree Rotations (线段树合并)
题解: 傻逼题 启发式合并线段树里面查$nlog^2$ 线段树合并顺便维护一下$nlogn$ 注意是叶子为n 总结点2n 代码: #include <bits/stdc++.h> usin ...
- BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对
原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...
- bzoj 2212 : [Poi2011]Tree Rotations (线段树合并)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换. 实现 ...
- BZOJ.2212.[POI2011]Tree Rotations(线段树合并)
题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...
随机推荐
- 不引用第三方变量交换a和b的值
方法一:(可操作字符) a = a^b; b = a^b; a = a^b; 方法二:(可操作字符) a=a+b; b=a-b; a=a-b; 方法三:(不可以操作字符) a=a*b; b=a/b; ...
- Python编程:从入门到实践 - matplotlib篇 - plot & scatter
matplotlib篇 plot & scatter # filename.py 获取当前文件名方法 import sys # 当前文件名 print(sys.argv[0]) # 去除后缀后 ...
- django-5-自定义模板过滤器及标签
<<<代码布局(自定义的代码放哪里)>>> (1)某个app特有的 1.一般放app目录下 固定名为templatetags 的python文件夹里鸭,如果是别的 ...
- RobotFrameWork+APPIUM实现对安卓APK的自动化测试----第五篇【AppiumLibrary校验函数介绍】
http://blog.csdn.net/deadgrape/article/details/50619050 以上连作者先跪一下方便面,在上一篇中,作者遗漏了两个常用的函数: 1.长按 Long P ...
- 2015 Multi-University Training Contest 10 hdu 5407 CRB and Candies
CRB and Candies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- BA-siemens-点位类型表
X(超级点) 输入 0-10v 4-20ma(不可用) Ni 1000 Pt 1000 10k & 100k 热敏电阻 数字输入 脉冲计数输入 输出 0-10v 4-20ma(不可用) 数字 ...
- [React Router] Prevent Navigation with the React Router Prompt Component
In this lesson we'll show how to setup the Prompt component from React Router. We'll prompt with a s ...
- Fibbonacci Number(杭电2070)
/*Fibbonacci Number Problem Description Your objective for this question is to develop a program whi ...
- DatabaseMetaData开发实务
1.总论 在企业开发实务中,数据迁移是经常会遇到的事情,此时,需要搞清楚,源数据库与目的数据库之间表以及表内部各列之间的异同.而有些时候,我们拿到的项目文 档,未必能准确表述各个表的准确结构,即使应用 ...
- DB-MySql:MySQL 及 SQL 注入
ylbtech-DB-MySQL:MySQL 及 SQL 注入 1.返回顶部 1. MySQL 及 SQL 注入 如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL ...