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 ...
随机推荐
- TCP三次握手和四次握手全过程 为什么要三次握手而不是二次握手?
三次握手 第一次握手: 客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送 ...
- springboot结合jpa
idea中新建springboot项目,引入spring-boot-starter-data-jpa依赖 application.yml中配置数据库连接,示例如下: spring: datasourc ...
- MIPI CSI2-TX接口基于FPGA实现
MIPI CSI2-TX用途: 跟海思的3559A芯片进行图像数据传输: MIPI CSI2-TX接口特性: xilinx 7系列芯片最大支持1.25Gbps: 最大支持lanes数量为4: 支持的图 ...
- MRP进程起不来, 报错:ORA-00600: internal error code, arguments: [2619], [227424], [], [], [], [], [], [], [], [], [], []
问题背景:客户数据库服务架构为一主一备,某日备库操作系统意外重启,重启后Oracle MRP进程起不来,报错:ORA-00600: internal error code, arguments: [2 ...
- Numpy数组解惑
参考: 理解numpy的rollaxis与swapaxes函数:https://blog.csdn.net/liaoyuecai/article/details/80193996 Numpy数组解惑: ...
- Java内存模型总结
Java内存模型 内存模型可以理解为在特定的操作协议下,对特定的内存或者高速缓存进行读写访问的过程抽象,不同架构下的物理机拥有不一样的内存模型,Java虚拟机也有自己的内存模型,即Java内存模型(J ...
- apply、bind、call方法的作用与区别
js中call.apply.bind方法的作用和区别 1. call方法 作用:专门用于修改方法内部的 this 指向 格式:xxx.call( 对象名, 参数1, 参数2 , ...);.即:将 x ...
- 渗透测试-基于白名单执行payload--Odbcconf
复现亮神课程 基于白名单执行payload--Odbcconf 0x01 Odbcconf简介: ODBCCONF.exe是一个命令行工具,允许配置ODBC驱动程序和数据源. 微软官方文档:https ...
- [BZOJ3029] 守卫者的挑战
Description 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜寻着关押applepi的监狱的所在地.突然,眼前一道亮光闪过.“我,Nizem,是黑魔法圣殿的守卫者.如果你能通过 ...
- MOOC python笔记(三) 序列容器:字符串、列表、元组
容器概念 容器是Python中的重要概念,分为有序与无序. 有序容器也称为序列类型容器,如:字符串.列表. 通用序列容器操作 容器连接+ 加号可以把两个序列连接成一个更大的容器,相加后两个序列的值并不 ...