bzoj 2212 Tree Rotations
bzoj 2212 Tree Rotations
- 考虑一个子树 \(x\) 的左右儿子分别为 \(ls,rs\) .那么子树 \(x\) 内的逆序对数就是 \(ls\) 内的逆序对数,\(rs\) 内的逆序对数,跨越 \(ls,rs\) 的逆序对数三者之和.
- 交换 \(ls,rs\) 显然对前两种的答案没有影响,只需最大化最后一种答案.
- 对每个叶子节点开一棵权值线段树向上合并,选取权值中点 \(mid\) 划分开,那么两种情况在当前层产生的贡献即为 \(ls\) 的左子树大小 \(\times\) \(rs\) 的右子树大小,\(ls\) 的右子树大小 \(\times\) \(rs\) 的左子树大小中的最大值.
- 继续递归合并,就可以计算到所有贡献.
- 时间复杂度为 \(O(nlogn)\) .
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
fh=-1,jp=getchar();
while (jp>='0'&&jp<='9')
out=out*10+jp-'0',jp=getchar();
return out*fh;
}
const int MAXN=2e5+10;
ll ans=0,ans1,ans2;
struct node{
int siz,ls,rs;
}Tree[MAXN*30];
#define root Tree[o]
#define lson Tree[root.ls]
#define rson Tree[root.rs]
#define t(x) Tree[x]
int n,cnt=0;
void update(int &o,int l,int r,int pos)
{
if(!o)
o=++cnt;
++root.siz;
if(l==r)
return;
int mid=(l+r)>>1;
if(pos<=mid)
update(root.ls,l,mid,pos);
else
update(root.rs,mid+1,r,pos);
}
int merge(int ls,int rs)
{
if(!ls || !rs)
return ls+rs;
t(ls).siz+=t(rs).siz;
ans1+=1LL*(Tree[t(ls).ls].siz)*(Tree[t(rs).rs].siz);
ans2+=1LL*(Tree[t(ls).rs].siz)*(Tree[t(rs).ls].siz);
t(ls).ls=merge(t(ls).ls,t(rs).ls);
t(ls).rs=merge(t(ls).rs,t(rs).rs);
return ls;
}
int solve()
{
int p=read(),x=0;
if(!p)
{
int ls=solve();
int rs=solve();
ans1=ans2=0;
x=merge(ls,rs);
ans+=min(ans1,ans2);
return x;
}
else
update(x,1,n,p);
return x;
}
int main()
{
n=read();
solve();
cout<<ans<<endl;
return 0;
}
bzoj 2212 Tree Rotations的更多相关文章
- [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】
题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...
- BZOJ 2212: [Poi2011]Tree Rotations( 线段树 )
线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子. #include<bits/stdc++.h> using namespace std; #defi ...
- 2212: [Poi2011]Tree Rotations
2212: [Poi2011]Tree Rotations https://www.lydsy.com/JudgeOnline/problem.php?id=2212 分析: 线段树合并. 首先对每个 ...
- BZOJ2212: [Poi2011]Tree Rotations
2212: [Poi2011]Tree Rotations Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 391 Solved: 127[Submi ...
- 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并
[BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...
- POI2011 Tree Rotations
POI2011 Tree Rotations 给定一个n<=2e5个叶子的二叉树,可以交换每个点的左右子树.要求前序遍历叶子的逆序对最少. 由于对于当前结点x,交换左右子树,对于范围之外的逆序对 ...
- bzoj 2212: [Poi2011]Tree Rotations
Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...
- BZOJ 2212 [Poi2011]Tree Rotations(线段树合并)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2212 [题目大意] 给出一棵二叉树,每个叶节点上有一个权值,现在可以任意交换左右儿子, ...
- bzoj 2212 : [Poi2011]Tree Rotations (线段树合并)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2212 思路:用线段树合并求出交换左右儿子之前之后逆序对的数量,如果数量变小则交换. 实现 ...
随机推荐
- 3 、操作元素 (属性 CSS 和 文档处理)
3 操作元素-属性 CSS 和 文档处理 3.1 属性操作 $("p").text() $("p").html() $(":check ...
- Java backup
待补充 ........ 0:常用头文件(待补充) import java.util.Arrays; import java.util.HashSet; import java.util.TreeSe ...
- Java 泛型通配符上限和通配符下限
①为什么要使用泛型通配符 请参考这篇随笔的下半部分 https://www.cnblogs.com/baxianhua/p/9194369.html ②通配符上限和通配符下限的简单解释 <? ...
- Conductor
https://netflix.github.io/conductor/ High Level Architecture
- 20189215《Linux内核原理与分析》第一周作业
实验1 Linux系统简介 本节主要学习了 Linux 的历史,Linux 与 Windows 的区别等入门知识.通过学习,我明确了目的,是要用 Linux 来做程序开发.搭建服务器等:并且非常接受不 ...
- 20155201 实验二《Java面向对象程序设计》实验报告
20155201 实验二<Java面向对象程序设计>实验报告 一.实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. ...
- Applet初次使用
ZLYD团队Apllet学习笔记 初识Applet Applet是采用Java编程语言编写的小应用程序,该程序可以包含在 HTML(标准通用标记语言的一个应用)页中,与在页中包含图像的方式大致相同.J ...
- 设置VS快捷代码片段
一.自定义sinppets方式 1.在VS安装路径[D:\vs2013\VC\Snippets\2052\Visual C++]下新建一个snippt文件 2.添加代码 <?xml versio ...
- linux下如何关闭某个tmux窗口
答:分成两个步骤,如下: 1.列出当前的tmux窗口 jello@jello:~$ tmux ls 1: 1 windows (created Tue Jan 17 09:28:05 2019) [2 ...
- POJ 1062 昂贵的聘礼(最短路)题解
题意:中文题意不解释... 思路:交换物品使得费用最小,很明显的最短路,边的权值就是优惠的价格,可以直接用Dijkstra解决.但是题目中要求最短路路径中任意两个等级不能超过m,我们不能在连最短路的时 ...