loj2163 / bzoj2212 / P3521 [POI2011]ROT-Tree Rotations(线段树合并)
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(线段树合并)的更多相关文章
- 【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/zhouzhendong/p/8079786.html 题目传送门 - BZOJ2212 题意概括 给一棵n(1≤n≤200000个叶子的二叉树, ...
- bzoj2212[Poi2011]Tree Rotations [线段树合并]
题面 bzoj ans = 两子树ans + min(左子在前逆序对数, 右子在前逆序对数) 线段树合并 #include <cstdio> #include <cstdlib> ...
- BZOJ2212【POI2011】ROT:Tree Rotation 线段树合并
题意: 给一棵n(1≤n≤200000个叶子的二叉树,可以交换每个点的左右子树,要求叶子遍历序的逆序对最少. 分析: 求逆序对我们可以想到权值线段树,所以我们对每个点建一颗线段树(为了避免空间爆炸,采 ...
- BZOJ.2212.[POI2011]Tree Rotations(线段树合并)
题目链接 \(Description\) 给定一棵n个叶子的二叉树,每个叶节点有权值(1<=ai<=n).可以任意的交换两棵子树.问最后顺序遍历树得到的叶子权值序列中,最少的逆序对数是多少 ...
- [bzoj2212]Tree Rotations(线段树合并)
解题关键:线段树合并模板题.线段树合并的题目一般都是权值线段树,因为结构相同,求逆序对时,遍历权值线段树的过程就是遍历所有mid的过程,所有能求出所有逆序对. #include<iostream ...
- Bzoj P2212 [Poi2011]Tree Rotations | 线段树合并
题目链接 通过观察与思考,我们可以发现,交换一个结点的两棵子树,只对这两棵子树内的节点的逆序对个数有影响,对这两棵子树以外的节点是没有影响的.嗯,然后呢?(っ•̀ω•́)っ 然后,我们就可以对于每一个 ...
- 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 ...
随机推荐
- ajax如何上传文件
PHP: <?php /** * Created by PhpStorm. * User: DELL * Date: 2017/11/23 * Time: 10:57 */ header(&qu ...
- C++异常 返回错误码
一种比异常终止更灵活的方法是,使用函数的返回值来指出问题.例如,ostream类的get(void)成员ASCII码,但到达文件尾时,将返回特殊值EOF.对hmean()来说,这种方法不管用.任何树脂 ...
- iOS设计模式之类族(class cluster)
类族模式在UIKit(user interface framework)使用的范围已经远远超过我们的想象,比如,UIButton,NSArray,NSString,NSNumber等, 例如NSNum ...
- 如何理解精通PHP ?
「精通 PHP」可以理解为以下三个: 精通「PHP 解析器 精通「PHP 语法.函数(这门语言) 精通「PHP 项目开发 1 精通「PHP 解析器」 可以从这里开始学习: PHP核心:骇客指南 :ht ...
- Fragments (官方文档中文版)
转 http://blog.sina.com.cn/s/blog_69a4fbd70100r5j4.html 概述 Fragment表现Activity中UI的一个行为或者一部分.可以将多个f ...
- webpack中,require的五种用法
a.js: module.exports = function(x){ console.log(x); } 一,commonjs同步: var b = require('./a');b('你好')// ...
- CCNP
CCNP全称是:Cisco Certified Network Professional——思科认证网络高级工程师.CCNP专业人员表示通过认证的人员具有丰富的网络知识.获得CCNP认证的专业人员可以 ...
- COGS 1224. [SHOI2002]百事世界杯之旅(期望概率)
COGS 1224. [SHOI2002]百事世界杯之旅 ★ 输入文件:pepsi.in 输出文件:pepsi.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] ...
- linux显示文件列表命令ls,使用ls --help列出所有命令参数
ls命令的相关参数 在提示符下输入ls --help ,屏幕会显示该命令的使用格式及参数信息: 先介绍一下ls命令的主要参数: -a 列出目录下的所有文件,包括以 . 开头的隐含文件. -A 显示除 ...
- Charles(网络封包分析工具)
一.what Charles工具是通过将自己设置成系统的网络访问代理服务器,使得所有的网络访问请求都通过它来完成,从而实现了网络封包的截取和分析. 它能实现以下 支持SSL代理:截取分析SSL的请求. ...