博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj2212 Tree Rotations 线段树合并+动态开点
阅读量:4591 次
发布时间:2019-06-09

本文共 1450 字,大约阅读时间需要 4 分钟。

思路:

  区间合并线段树的题,第一次写,对于一颗子树,无论这个子树怎么交换,都不会对其他子树的逆序对造成影响,所以就直接算逆序对就好。

  注意叶子节点是1到n的全排列,所以每个权值都只会出现1次,合并很好写。

  注意动态开点,最多n个叶子节点,然后每次查询用到log个子树节点,(这句话似乎有语病)所以要开nlogn的空间。

#include
#define clr(a,b) memset(a,b,sizeof(a))#define fpn() freopen("simple.in","r",stdin)using namespace std;typedef long long ll;const int inf=0x3f3f3f3f;const int maxn=200005;int n,q,tot,r,k,cnt;int R[maxn*30],rt[maxn*30],L[maxn*30],val[maxn*30],ch[maxn*30][2];ll sum[maxn*30],ans,anl,anr;void read(int &r){ r=++tot; scanf("%d",&val[r]); if(!val[r]){ read(ch[r][0]); read(ch[r][1]); }}void pushup(int x){ sum[x]=sum[L[x]]+sum[R[x]];}void insert(int &x,int l,int r,int p){ x=++cnt; int mid=(l+r)>>1; if(l==r){ sum[x]=1; return; } if(p<=mid)insert(L[x],l,mid,p); else insert(R[x],mid+1,r,p); pushup(x);}int merge(int x,int y){ if(!x)return y; if(!y)return x; anl+=sum[L[x]]*sum[R[y]]; anr+=sum[L[y]]*sum[R[x]]; L[x]=merge(L[x],L[y]); R[x]=merge(R[x],R[y]); pushup(x); return x;}ll dfs(int x){ ll ans=0; if(!val[x]){ ans+=dfs(ch[x][0])+dfs(ch[x][1]); anl=anr=0; rt[x]=merge(rt[ch[x][0]],rt[ch[x][1]]); ans+=min(anl,anr); }else{ insert(rt[x],1,n,val[x]); } return ans;}int main(){ scanf("%d",&n); read(r); ans=dfs(1); cout<
<
View Code

 

转载于:https://www.cnblogs.com/mountaink/p/10421234.html

你可能感兴趣的文章
win8设置自动关机
查看>>
什么是java序列化,如何实现java序列化?
查看>>
创建动态节点和动态Table
查看>>
软工实践第三次结对作业——原型设计
查看>>
机器学习之路: python 回归树 DecisionTreeRegressor 预测波士顿房价
查看>>
以太坊2.0原理详解 - 开篇(一)
查看>>
PHP学习笔记-变量-动态变量,变量类型检测以及变量销毁
查看>>
【模拟赛·食物中毒】
查看>>
ZOJ 3946 Highway Project 贪心+最短路
查看>>
HDOJ 1069_大二写
查看>>
第二次作业 孙美玉
查看>>
Debian安装JAVA环境(转载)
查看>>
JavaScript--浅谈DOM操作
查看>>
Ocelot网关统一查看多个微服务asp.net core项目的swagger API接口
查看>>
《算法图解》笔记(1) 二分查找
查看>>
TCP/IP和Socket的关系
查看>>
EasyNVR摄像机H5流媒体服务器在windows上批处理脚本自动以管理员权限运行
查看>>
使用btoa和atob来进行Base64转码和解码
查看>>
201521123006 《java程序设计》 第8周学习总结
查看>>
网络对抗作业一
查看>>