[POI2011]Rotacje na drzewie (2)

题目大意:

一棵有\(n\)个叶子结点的二叉树,每个叶子结点有一个权值,恰好是\(1\sim n\)的一个排列,你可以任意交换每一对子结点,使得从左往右的权值序列中,逆序对数量最少,求最少逆序对数。

原题:\(n\le2\times10^5\),空间限制64MB;

加强版:\(n\le10^6\),空间限制128MB。

思路:

原题可以直接使用线段树合并,注意空间回收即可通过此题。

加强版可以使用pb_ds红黑树按秩和并。

源代码1:

#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
int n;
int64 cnt0,cnt1,ans;
struct Node {
Node *left,*right;
int sum;
Node():left(NULL),right(NULL),sum(0) {}
};
inline int count(const Node *const &p) {
return p?p->sum:0;
}
Node *build(const int &b,const int &e,const int &x) {
Node *p=new Node;
p->sum++;
if(b==e) return p;
const int mid=(b+e)>>1;
if(x<=mid) p->left=build(b,mid,x);
if(x>mid) p->right=build(mid+1,e,x);
return p;
}
Node *merge(Node *p,Node *q,const int &b,const int &e) {
if(!p||!q) return p?:q;
p->sum+=q->sum;
if(b==e) {
delete q;
return p;
}
const int mid=(b+e)>>1;
cnt0+=(int64)count(p->left)*count(q->right);
cnt1+=(int64)count(q->left)*count(p->right);
p->left=merge(p->left,q->left,b,mid);
p->right=merge(p->right,q->right,mid+1,n);
delete q;
return p;
}
Node* solve() {
const int w=getint();
if(w!=0) {
return build(1,n,w);
} else {
Node *p=merge(solve(),solve(),1,n);
ans+=std::min(cnt0,cnt1);
cnt0=cnt1=0;
return p;
}
}
int main() {
n=getint();
solve();
printf("%lld\n",ans);
return 0;
}

源代码2:

#include<cstdio>
#include<cctype>
#include<functional>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
typedef __gnu_pbds::tree<int,__gnu_pbds::null_type,std::less<int>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update> rbt;
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
typedef unsigned long long uint64;
int n;
int64 ans;
inline rbt *merge(rbt *p,rbt *q) {
if(p->size()<q->size()) std::swap(p,q);
uint64 tmp=0;
for(int x:*q) tmp+=p->order_of_key(x);
ans+=std::min(1ll*p->size()*q->size()-tmp,tmp);
for(int x:*q) p->insert(x);
delete q;
return p;
}
rbt *solve() {
const int w=getint();
if(w!=0) {
rbt *p=new rbt;
p->insert(w);
return p;
} else {
return merge(solve(),solve());
}
}
int main() {
n=getint();
solve();
printf("%lld\n",ans);
return 0;
}

[POI2011]Rotacje na drzewie (2)/[BZOJ3702]二叉树的更多相关文章

  1. bzoj3702二叉树 线段树合并

    3702: 二叉树 Time Limit: 15 Sec  Memory Limit: 256 MBSubmit: 600  Solved: 272[Submit][Status][Discuss] ...

  2. [bzoj3702] 二叉树

    一个节点的儿子是否交换,不会影响到它和兄弟节点间的逆序对数. 所以每次合并线段树的时候算一下交换与不交换的逆序对数,然后选个较小值就行了. #include<cstdio> #includ ...

  3. [bzoj3702/2212][Poi2011]二叉树/Tree Rotations_线段树

    二叉树 Tree Rotations bzoj-3702 bzoj-2212 Poi-2011 题目大意:现在有一棵二叉树,所有非叶子节点都有两个孩子.在每个叶子节点上有一个权值(有n个叶子节点,满足 ...

  4. bzoj3702/bzoj2212 二叉树 (线段树合并)

    用线段树记每个子树中包含的数,然后合并的时候算出来逆序对的数量(合并a,b时,就是size[ch[a][1]]*size[ch[b][0]]),来决定这个子树要不要翻转 #include<bit ...

  5. 二叉树hdu1710

    学习二叉树,看了两天也不明白,唉!acm之路让我体验到要付出巨大的努力,废话不多说,看我网上找到的代码: 此题题意很明确,给你先序遍历,中序遍历,求后序遍历.但代码就让我找不到东西了. http:// ...

  6. BZOJ2212: [Poi2011]Tree Rotations

    2212: [Poi2011]Tree Rotations Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 391  Solved: 127[Submi ...

  7. BZOJ 2212: [Poi2011]Tree Rotations( 线段树 )

    线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子. #include<bits/stdc++.h> using namespace std; #defi ...

  8. python实战--数据结构二叉树

    此文将讲述如何用python实战解决二叉树实验 前面已经讲述了python语言的基本用法,现在让我们实战一下具体明确python的用法 点击我进入python速成笔记 先看一下最终效果图: 首先我们要 ...

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

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

随机推荐

  1. Linux文件系统2---VFS的四个主要对象

    1.引言 本文所述关于文件管理的系列文章主要是对陈莉君老师所讲述的文件系统管理知识讲座的整理. Linux可以支持不同的文件系统,它源于unix文件系统,也是unix文件系统的一大特色. Linux文 ...

  2. 笔记软件 notion

    笔记软件 notion :     https://www.notion.so 注册:zengxinle@126.com     团队:Hopesun

  3. Linux下rsyslog日志收集服务环境部署记录【转】

    rsyslog 可以理解为多线程增强版的syslog. 在syslog的基础上扩展了很多其他功能,如数据库支持(MySQL.PostgreSQL.Oracle等).日志内容筛选.定义日志格式模板等.目 ...

  4. nodejs 使用mysql 进行查询的问题

    因为返回的是个对象 var selectSql1="select * from spc_word_mst where WORD_ID=? limit 0,1 "var select ...

  5. jvm系列一、java类的加载机制

    一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  6. 关于Java Web应用中的配置部署描述符web.xml

    一.web.xml概述 位于每个Web应用的WEB-INF路径下的web.xml文件被称为配置描述符,这个 web.xml文件对于Java Web应用十分重要,每个Java Web应用都必须包含一个w ...

  7. 14-jQuery补充

    jquery内容补充 jquery除了咱们上面讲解的常用知识点之外,还有jquery 插件.jqueryUI知识点 jqueryUI 官网: https://jqueryui.com/ jqueryU ...

  8. PYTHON-文件指针的移动,移动和函数基础

    # 文件内指针的移动 #大前提:文件内指针的移动是Bytes为单位的,唯独t模式下的read读取内容个数是以字符为单位 # f.seek(指针移动的字节数,模式控制): 控制文件指针的移动# 模式控制 ...

  9. ubuntu预装的是vim tiny版本

    可以安装vim full版本,在full版本下键盘正常,安装好后同样使用vi命令.安装vim: ubuntu预装的是vim tiny版本,而需要的是vim full版本.执安装vim full版本:$ ...

  10. hdu3436 splaytree树模拟队列+离散化缩点

    数据较大,需要先把每个top不会操作到的段缩成一个点,记录其开始和结束的位置,和top能操作到的点一起建立一颗伸展树模拟 然后就是普通的队列模拟操作 /* 不会被top操作到的区间就缩点 通过spla ...