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$

翻转时,逆序对数量:$a[a[a[rt].lc].lc].sum*a[a[a[rt].rc].rc].sum$

递归处理即可。


重点是合并线段树:

前提:两棵动态开点线段树

实现(将树$pr$合并到$o$上):

void merge(int &o,int pr){
if(!o||!pr) {o=o+pr;return;}//一棵为空则返回另一边
a[o].sum+=a[pr].sum;
.......//结算信息
merge(a[o].lc,a[pr].lc);
merge(a[o].rc,a[pr].rc); //递归合并
}

蓝后就结束了。


 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#define re register
using namespace std;
typedef long long ll;
char gc(){
static char buf[],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2)?EOF:*p1++;
}
void read(int &x){
char c=gc();x=;
while(!isdigit(c)) c=gc();
while(isdigit(c)) x=(x<<)+(x<<)+(c^),c=gc();
}//以上读入优化
ll min(ll &a,ll &b){return a<b?a:b;}
struct node{int sum,lc,rc;}a[];
int n,u,rt; ll res1,res2,ans;
void update(int &o,int l,int r,int v){
if(!o) o=++u;
++a[o].sum;
if(l==r) return;
int mid=l+((r-l)>>);
if(v<=mid) update(a[o].lc,l,mid,v);
else update(a[o].rc,mid+,r,v);
}
void merge(int &o,int pr){//把o/pr当作左/右子树,合并到左子树
if(!o||!pr) {o=o+pr;return;}
a[o].sum+=a[pr].sum;
res1+=1ll*a[a[o].lc].sum*a[a[pr].rc].sum; //翻转:lc->lc 和 rc->rc 之间的逆序对数
res2+=1ll*a[a[o].rc].sum*a[a[pr].lc].sum; //不翻转:lc->rc 和 rc->lc 之间的逆序对数
merge(a[o].lc,a[pr].lc); //合并线段树,并计算 lc->lc 和 rc->lc 之间的逆序对数
merge(a[o].rc,a[pr].rc); //同上
}
void dfs(int &x){//题意的神奇递归输入
int q,lc,rc; read(q);
if(!q){
dfs(lc); dfs(rc);
res1=res2=;
merge(x=lc,rc);//合并
ans+=min(res1,res2);//选代价小的
}else update(x=,,n,q);//给叶子结点单独建一棵线段树,后面再合并
}
int main(){
// freopen("P3521_2.in","r",stdin);
read(n); dfs(rt);
printf("%lld",ans);
return ;
}

loj2163 / bzoj2212 / P3521 [POI2011]ROT-Tree Rotations(线段树合并)的更多相关文章

  1. 【BZOJ2212】[Poi2011]Tree Rotations 线段树合并

    [BZOJ2212][Poi2011]Tree Rotations Description Byteasar the gardener is growing a rare tree called Ro ...

  2. BZOJ2212 [Poi2011]Tree Rotations 线段树合并 逆序对

    原文链接http://www.cnblogs.com/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...

  3. bzoj2212[Poi2011]Tree Rotations [线段树合并]

    题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...

  4. BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并

    题意: 给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求叶子遍历序的逆序对最少. 分析: 求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采 ...

  5. BZOJ.2212.[POI2011]Tree Rotations(线段树合并)

    题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...

  6. [bzoj2212]Tree Rotations(线段树合并)

    解题关键:线段树合并模板题.线段树合并的题目一般都是权值线段树,因为结构相同,求逆序对时,遍历权值线段树的过程就是遍历所有mid的过程,所有能求出所有逆序对. #include<iostream ...

  7. Bzoj P2212 [Poi2011]Tree Rotations | 线段树合并

    题目链接 通过观察与思考,我们可以发现,交换一个结点的两棵子树,只对这两棵子树内的节点的逆序对个数有影响,对这两棵子树以外的节点是没有影响的.嗯,然后呢?(っ•̀ω•́)っ 然后,我们就可以对于每一个 ...

  8. bzoj2212/3702 [Poi2011]Tree Rotations 线段树合并

    Description Byteasar the gardener is growing a rare tree called Rotatus Informatikus. It has some in ...

  9. bzoj2212 Tree Rotations 线段树合并+动态开点

    题目传送门 思路: 区间合并线段树的题,第一次写,对于一颗子树,无论这个子树怎么交换,都不会对其他子树的逆序对造成影响,所以就直接算逆序对就好. 注意叶子节点是1到n的全排列,所以每个权值都只会出现1 ...

  10. BZOJ_2212_[Poi2011]Tree Rotations_线段树合并

    BZOJ_2212_[Poi2011]Tree Rotations_线段树合并 Description Byteasar the gardener is growing a rare tree cal ...

随机推荐

  1. 关于word文档转成html网页的方法

    在工作中,有时我们可能需要将一个word文档转换成html网页格式,如在写帮助文档的时候,采用office编写,最终却想以网页的格式传到网站的指定目录下供网友直接浏览 这时我们就需要对word文件进行 ...

  2. Unity3D笔记十二 游戏元素二之摄像机

    一.摄像机 摄像头用以捕捉和显示的世界给玩家.通过自定义和操纵相机,你可以让你的游戏的呈现真正独一无二的.您可以在一个场景无限数量的摄像机.它们可以设置在任何顺序呈现在屏幕上的任何地方,或者屏幕的某些 ...

  3. 3.html+.ashx(删除学生信息)

    C03ListStu.ashx 0:false(删除);1:true(正常). (数据库里定义个BOOL型,TRUE表示正常FALSE表示删除) <html> <head> & ...

  4. SaltStack部署redis主从

    需求: 一,部署redis主从,一台主一台从 二,redis监听自己的IP地址,而不是0.0.0.0 主:安装,配置,启动 从:安装,配置,启动,主从

  5. Python+ Calibre 处理 中文报纸

    import re ##2 line='<a href=nw.D110000renmrb_20180401_1-01.htm><script>document.write(vi ...

  6. Lodash 常用API中文参考

    lodash和underscore都是现在非常流行的两个javascript库,提供了一套函数式编程的实用功能. 而lodash本身最初也是underscore的一个fork,因为和其他(Unders ...

  7. 使用pidstat查看进程资源使用情况

    简介 pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存.设备IO.任务切换.线程等.pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上 ...

  8. DNS named. bind linux (ACL/View)---dnsmasq-with docker,hosts in docker.

    [bind--named.conf] https://blog.csdn.net/z_yttt/article/details/53020814 [Docker搭建dnsmasq] https://b ...

  9. flask中secret_key的作用

    https://segmentfault.com/q/1010000007295395

  10. Python开发【Django】:Model操作(二)

    Model操作 1.操作汇总: # 增 # # models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs # obj ...