【codeforces685B686D】【Kay and Snowflake】【线段树合并】
2016-06-26 20:28
288 查看
题目大意
给定30万个点的树,要求支持30万个询问,询问以某个点为根的子树的重心。
题解
给每的节点建立权值线段树,记录每个子节点为根的子树大小。重心为根的子树大小最接近但大于全树大小的一半。使用线段树合并即可解决本问题。
code
#include<set> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define fo(i,j,k) for(int i=j;i<=k;i++) #define fd(i,j,k) for(int i=j;i>=k;i--) using namespace std; int const maxn=300000; int cntgra,cntpon,n,q,to[maxn+10],next[maxn+10],begin[maxn+10],tsize[maxn*18*2+10],son[maxn*18*2+10][2], pon[maxn*18*2+10],ans[maxn+10],size[maxn+10]; void insert(int u,int v){ to[++cntgra]=v; next[cntgra]=begin[u]; begin[u]=cntgra; } int merge(int u,int v){ if(!tsize[u])return v; if(!tsize[v])return u; son[u][0]=merge(son[u][0],son[v][0]); son[u][1]=merge(son[u][1],son[v][1]); tsize[u]=tsize[son[u][0]]+tsize[son[u][1]]; return u; } int ask(int now,int l,int r,int tg){ int m=(l+r)/2; if(!tsize[now])return 0; if(l==r)return pon[now]; if(tg<=m){ int tmp=ask(son[now][0],l,m,tg); if(tmp)return tmp; else return ask(son[now][1],m+1,r,tg); } else return ask(son[now][1],m+1,r,tg); } void change(int now,int l,int r,int tg,int v){ int m=(l+r)/2; tsize[now]++; if(l==r)pon[now]=v; else if(tg<=m){ if(!son[now][0])son[now][0]=++cntpon; change(son[now][0],l,m,tg,v); } else{ if(!son[now][1])son[now][1]=++cntpon; change(son[now][1],m+1,r,tg,v); } } void dfs(int now){ size[now]=1; for(int i=begin[now];i!=-1;i=next[i]){ dfs(to[i]); size[now]+=size[to[i]]; son[now][0]=merge(son[now][0],son[to[i]][0]); son[now][1]=merge(son[now][1],son[to[i]][1]); } change(now,1,n,size[now],now); ans[now]=ask(now,1,n,(size[now]+1)/2); } int main(){ scanf("%d%d",&n,&q); memset(begin,255,sizeof(begin));cntpon=n; fo(i,2,n){ int x;scanf("%d",&x); insert(x,i); } dfs(1); fo(i,1,q){ int x;scanf("%d",&x); printf("%d\n",ans[x]); } return 0; }
相关文章推荐
- 互联网金融项目——工作日志(二)之点滴积累
- Android文件存储(二)与ContentProvider
- 15PL_SQL过程之游标的使用
- hdu 4522(图论,构图)
- UDP网路会议室的代码
- 数据的离散化处理
- PHP中的final/static
- C++编写封装驱动接口时::符号的意思
- php 错误信息配置
- hdu 5067(状态压缩dp)
- 华为机试---奖学金
- 面试指导
- 接口和抽象类有什么区别
- MariaDB 在Linux下设置编码
- 学习使用web of science查找文献
- Easy to understand Dynamic Programming – Edit distance
- Error Unable to start the Genymotion virtual device.解决
- 14PL_SQL之用表存储错误信息
- JAVAweb 实现导入导出
- 互联网金融项目——工作日志(一)之点滴积累