P3521 [POI2011]ROT-Tree Rotations(线段树合并)
一句话题意(不用我改了.....):给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少。
......这题输入很神烦呐。。。
给你一棵二叉树的dfs序(考场上没发现2333),只有叶子结点有值,然后求逆序对大小
在考场上,建树建了好久,然后暴力暴了好久,然后得到了0分的好成绩呢(我真棒)
正解其实也不难想(但是当时不会权值线段树)
题解:
其实很简单,想想:对于一层的逆序对,数量是一定的。也就是说,无论怎么转当前子树,对上一层的逆序对数量是没有影响的。
挺好理解的但是还是上张图吧:

对于第二层来说,无论左边的2,3怎么改变,相对于右边4,1或1,4的逆序对个数始终不会改变。
这个性质吼啊
于是我们只需要求块内的最小逆序对个数就行了。
然后再考虑怎么求逆序对个数。
首先,权值线段树是一个桶,而且下标是有序的(废话)
然后,两课权值线段树在本题中是等价的,也就是说,左右要合并的线段树,除了维护的区间&&存储元素不一样,是满足可并线段树的条件的。
所以,对于一个区间,逆序对只需要比较左区间的右半边(桶中)数量*右区间的左半边就行了,
然后再比较swap之后的,贪心地取下去,合并下去就行了。
.....语言表述有问题,看一下这一小段代码:
ans1+=(ll )t[t[l].rs].sum*t[t[r].ls].sum;
ans2+=(ll )t[t[l].ls].sum*t[t[r].rs].sum;
就这样,比较然后加小的,最后就是总答案了。
tips:真正明白了指针的好处,好好用啊,但是得注意一下,因为指针是直接改值,有些值不能改的话,得用一个中间变量记录。
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
#define ll long long
struct tree
{
int ls,rs,sum;
}t[maxn*];
ll ans=,ans1=,ans2=;
int n,pos;
int cnt=;
void insert(int &x,int l,int r)
{
if(!x)
{
x=++cnt;
}
t[x].sum++;
if(l==r)
{
return ;
}
int mid=(l+r)>>;
if(pos<=mid)
{
insert(t[x].ls,l,mid);
}
else
{
insert(t[x].rs,mid+,r);
}
}
void merge(int &l,int r)//直接指针合并,比原来的要好写
{
if(!l||!r)
{
l=l+r;
return ;
}
t[l].sum+=t[r].sum;
ans1+=(ll )t[t[l].rs].sum*t[t[r].ls].sum;
ans2+=(ll )t[t[l].ls].sum*t[t[r].rs].sum;
merge(t[l].ls,t[r].ls);
merge(t[l].rs,t[r].rs);
}
int work(int &x)
{
int T,ls,rs;
x=;
cin>>T;
if(!T)
{
work(ls);
work(rs);
ans1=ans2=;
x=ls;//指针,得用中间变量存储
merge(x,rs);
ans+=min(ans1,ans2);
}
else
{
pos=T;
insert(x,,n);
}
}
int main()
{
scanf("%d",&n);
int t=;
work(t);
printf("%lld",ans);
return ;
}
(完)
P3521 [POI2011]ROT-Tree Rotations(线段树合并)的更多相关文章
- 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并
[BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...
- bzoj2212[Poi2011]Tree Rotations [线段树合并]
题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...
- BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对
原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...
- BZOJ.2212.[POI2011]Tree Rotations(线段树合并)
题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...
- BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并
题意: 给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求叶子遍历序的逆序对最少. 分析: 求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采 ...
- Bzoj P2212 [Poi2011]Tree Rotations | 线段树合并
题目链接 通过观察与思考,我们可以发现,交换一个结点的两棵子树,只对这两棵子树内的节点的逆序对个数有影响,对这两棵子树以外的节点是没有影响的.嗯,然后呢?(っ•̀ω•́)っ 然后,我们就可以对于每一个 ...
- [bzoj2212]Tree Rotations(线段树合并)
解题关键:线段树合并模板题.线段树合并的题目一般都是权值线段树,因为结构相同,求逆序对时,遍历权值线段树的过程就是遍历所有mid的过程,所有能求出所有逆序对. #include<iostream ...
- bzoj2212/3702 [Poi2011]Tree Rotations 线段树合并
Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...
- bzoj2212 Tree Rotations 线段树合并+动态开点
题目传送门 思路: 区间合并线段树的题,第一次写,对于一颗子树,无论这个子树怎么交换,都不会对其他子树的逆序对造成影响,所以就直接算逆序对就好. 注意叶子节点是1到n的全排列,所以每个权值都只会出现1 ...
- BZOJ_2212_[Poi2011]Tree Rotations_线段树合并
BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...
随机推荐
- e课表项目第二次冲刺周期第六天
昨天干了什么? 昨天是这次冲刺周期的第五天,我们的冲刺周期已经快过了一半,我们已经实现了对第一层界面的设计,所以我们的进度和我们的时间正好吻合,所以我们有信心完成我们的软件.我在网上搜了一些关于监听的 ...
- PowerBI系列之什么是PowerBI
大家好,我是小黎子!一个专注于数据分析整体数据仓库解决方案的程序猿!今天小黎子就给大家介绍一个数据分析工具由Microsoft出品的全新数据可视化工具Power BI.微软Excel很早就支持了数据透 ...
- python3爬虫环境搭建
安装python3 sudo apt-get install python3-dev build-essential libssl-dev libffi-dev libxml2 libxml2-dev ...
- python 报错TypeError: 'range' object does not support item assignment,解决方法
贴问题 nums = range(5)#range is a built-in function that creates a list of integers print(nums)#prints ...
- Python_MySQL数据库的写入与读取
[需求]1. 在数据库中创建表,且能按时间自动创建新表 2. 数据写入数据库 3. 从数据库读取数据 1. 创建表,并自动更新 def Creat_Table(InitMySQL,tabel_name ...
- XSS扫盲到漏洞挖掘上手
复习xss ,也总结一下XSS基础的点到进阶的知识 目录 0x01 XSS扫盲入门 0x02 XSS payload构造 0x03 XSS payload变形进阶 0x01 XSS扫盲入门 XS ...
- insert into select 引起的 "子查询返回的值不止一个。当子查询跟随在**之后,或子查询用作表达式时,这种情况是不允许的"
目录 1.事故现场 1.1 在使用 Insert into Table2 select * from Table1 将表1的数据插入到表2时,报错如下: 1.2 sql 语句 2.推测 3.解决方案 ...
- Spring Boot - 访问外部接口最全总结
Spring Boot - 访问外部接口 在Spring-Boot项目开发中,存在着本模块的代码需要访问外面模块接口,或外部url链接的需求, 比如调用外部的地图API或者天气API. Spring ...
- C加加学习之路 1——开始
C++是一门古老而复杂的语言,绝不是一门可以速成的语言,学习它需要有意识的刻意练习和长时间的持续不断的磨练.而大多数人不太能耐得住寂寞,喜欢速成,所以像<21天学通C++>这种书就比较受欢 ...
- 双系统开机引导菜单修复方法 进win7无须重启|metro引导|双系统菜单名字修改
此文转自互联网,一部分是原创. 主要内容 1.修复双系统菜单(win7与win8双系统),进入win7不再需要重启,普通菜单样式(普通引导,非metro界面),更加简洁,实用,开机即可选择操作系统 2 ...