BZOJ[4756][Usaco2017 Jan]Promotion Counting 线段树合并
来源:互联网 发布:前端页面优化方案 编辑:程序博客网 时间:2024/05/22 05:48
题目链接http://www.lydsy.com/JudgeOnline/problem.php?id=4756
裸的线段树合并
对于每个点建一个权值线段树
这里采用了动态开点,常数较大(线段树范围是1~MAXN),但是省略了离散化
代码如下:
#include<ctype.h>#include<cstdio>#define N 100050using namespace std;const int INF=1000000000;///数最大这么多inline int read(){ int x=0,f=1;char c; do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c)); do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c)); return x*f;}int top,n,x;int ans[N],fir[N],a[N];struct Edge{ int to,nex; Edge(int _=0,int __=0):to(_),nex(__){}}nex[N];struct Node{ int sum,l,r; Node *ls,*rs; inline void maintain() { sum=ls->sum+rs->sum; } Node(int,int);}*root[N],*null;///定义一个null,可以省略好多问题(同平衡树那个)Node::Node(int _=0,int __=0):l(_),r(__){ sum=0; ls=rs=null;}inline void add(int x,int y){ nex[++top]=Edge(y,fir[x]); fir[x]=top;}void Add(int x,Node *&k,int L,int R){///L,R记录左右节点(动态开点用的) if(k==null) k=new Node(L,R);///动态开点,如果原先没有这个点就加上 if(k->l==k->r){ k->sum++; return; } int mid=L+R>>1; if(x<=mid) Add(x,k->ls,L,mid); else Add(x,k->rs,mid+1,R); k->maintain();}int Query(int l,int r,Node *k){ if(k==null) return 0; if(k->l>=l && k->r<=r){ return k->sum; } int mid=k->l+k->r>>1,t; if(mid>=r) t=Query(l,r,k->ls); else if(mid<l) t=Query(l,r,k->rs); else t=Query(l,r,k->ls)+Query(l,r,k->rs); k->maintain(); return t;}void Merge(Node *&x,Node *&y){ if(y==null) return; if(x==null){ x=y; return; } x->sum+=y->sum; Merge(x->ls,y->ls);Merge(x->rs,y->rs);}void Debug(Node *x){///调试orz.. if(x->ls!=null) Debug(x->ls); if(x->rs!=null) Debug(x->rs); printf("%d %d %d\n",x->l,x->r,x->sum);}void dfs(int x){ for(int i=fir[x];i;i=nex[i].nex){ dfs(nex[i].to); Merge(root[x],root[nex[i].to]);///求出子树答案后,合并到本节点上 } ans[x]=Query(a[x]+1,INF,root[x]);}int main(){ null=new Node(-1,-1); null->ls=null->rs=null; null->sum=0; n=read(); for(int i=1;i<=n;i++) a[i]=read(),root[i]=null; for(int i=2;i<=n;i++){ x=read(); add(x,i); } for(int i=1;i<=n;i++) Add(a[i],root[i],1,INF); dfs(1); for(int i=1;i<=n;i++){ printf("%d\n",ans[i]); }return 0;}
阅读全文
0 0
- bzoj 4756: [Usaco2017 Jan]Promotion Counting (线段树合并)
- BZOJ 4756 [Usaco2017 Jan]Promotion Counting 线段树合并
- BZOJ[4756][Usaco2017 Jan]Promotion Counting 线段树合并
- 4756: [Usaco2017 Jan]Promotion Counting 线段树合并
- bzoj 4756: [Usaco2017 Jan]Promotion Counting
- BZOJ 4756 [Usaco2017 Jan]Promotion Counting dfs序+主席树
- 4756: [Usaco2017 Jan]Promotion Counting
- BZOJ4756: [Usaco2017 Jan]Promotion Counting
- 【bzoj4756】[Usaco2017 Jan]Promotion Counting
- 【bzoj4756】[Usaco2017 Jan]Promotion Counting
- BZOJ 4756 Promotion Counting(线段树合并 || dfs)
- 【bzoj 4756】Promotion Counting(线段树合并)
- bzoj 4756: [Usaco2017 Jan]Promotion Counting dsu on tree+树状数组
- bzoj4756[Usaco2017 Jan]Promotion Counting 树上主席树
- USACO2016 Jan Bronze 1:Promotion Counting
- USACO2016 Jan Bronze 4:Promotion Counting
- [DP] BZOJ 4758 [Usaco2017 Jan]Subsequence Reversal
- BZOJ 4777 Usaco2017 Open Switch Grass Kruskal+线段树
- Java7特性中,abstract class和interface有什么区别
- 申请谷歌云服务器,运行Jupyter
- IDEA spring-boot jpa jsp 框架搭建(一)
- storm ack机制
- Android-数据库
- BZOJ[4756][Usaco2017 Jan]Promotion Counting 线段树合并
- SSM SpringMVC 批量删除
- 【转载】TensorFlow学习---tf.nn.dropout防止过拟合
- ubuntu proxychains and shadowsocks
- Ubuntu搭建LAMP环境
- window系统下,GO开发时,如何修改GOPATH?
- mysql提示连接数过大(1129错误)
- java技术体系的三个平台
- ARCGIS 时间类型