[练习][bzoj2783]二分+倍增 树
来源:互联网 发布:js实现鼠标特效 编辑:程序博客网 时间:2024/06/05 16:45
题目背景
bzoj2783
题目描述
给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。
输入格式
第一行是两个整数N和S,其中N是树的节点数。
第二行是N个正整数,第i个整数表示节点i的正整数。
接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
输出格式
输出路径节点总和为S的路径数量。
样例数据
输入
3 3
1 2 3
1 2
1 3
输出
2
备注
【数据范围】
对于100%数据,N≤100000,所有权值以及S都不超过1000。
分析:题目中的“路径中节点的深度必须是升序的”已经提示了倍增的方法找father,我们能在O(
代码
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>#include<set>using namespace std;int getint(){ int sum=0,f=1; char ch; for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar()); if(ch=='-') { f=-1; ch=getchar(); } for(;isdigit(ch);ch=getchar()) sum=(sum<<3)+(sum<<1)+ch-48; return sum*f;}const int maxn=100010;int n,s,ans;int w[maxn];int tot,first[maxn],nxt[maxn*2],to[maxn*2];int fa[maxn][20],sumw[maxn][20];void addedge(int x,int y){ tot++; nxt[tot]=first[x]; first[x]=tot; to[tot]=y; tot++; nxt[tot]=first[y]; first[y]=tot; to[tot]=x;}void dfs(int u,int f)//预处理fa、权值和{ fa[u][0]=f; sumw[u][0]=w[f]; for(int mi=1;mi<=19;++mi) { fa[u][mi]=fa[fa[u][mi-1]][mi-1]; sumw[u][mi]=sumw[u][mi-1]+sumw[fa[u][mi-1]][mi-1]; } for(int p=first[u];p;p=nxt[p]) { int v=to[p]; if(v!=f) dfs(v,u); }}int getw(int x,int dep)//计算从fa[x][0]到dep的权值和{ int res=0; for(int i=19;i>=0;--i) if(dep&(1<<i)) { res+=sumw[x][i]; x=fa[x][i]; } return res;}int erfen(int x)//二分向上跳的深度{ int l=0,r=100000,mid; while(l<=r) { mid=l+r>>1; int sumww=getw(x,mid)+w[x]; if(sumww<s) l=mid+1; else if(sumww>s) r=mid-1; else return 1; } return 0;}int main(){ freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); int x,y; n=getint(),s=getint(); for(int i=1;i<=n;++i) w[i]=getint(); for(int i=1;i<n;++i) { x=getint(),y=getint(); addedge(x,y); } dfs(1,0); ans=0; for(int i=1;i<=n;++i) ans+=erfen(i); cout<<ans<<'\n'; return 0;}
本题结。
阅读全文
0 0
- [练习][bzoj2783]二分+倍增 树
- 【bzoj2783】【JLOI2012】【树】【set】
- 【JLOI2012】【BZOJ2783】树
- bzoj2783【JLOI2012】树
- bzoj2783 JLOI2012 树
- bzoj2783: [JLOI2012]树
- 【bzoj2783】【JLOI2012】树
- bzoj2783 [JLOI2012]树 STL+dfs
- 【BZOJ2783】【DFS】[JLOI2012]树 题解
- BZOJ 2783 JLOI 2012 树 倍增+二分
- BZOJ 2783 JLOI2012 树 二分 + 倍增
- 暴力——BZOJ2783/Luogu3252 [JLOI2012]树
- 避难向导 树的直径 树上倍增 二分答案
- 【运输计划】【二分】【树上倍增】
- 二分新姿势--倍增法
- 二分练习
- 二分练习
- 二分练习
- 集合类set的一些比较
- POJ 3525 Most Distant Point from the Sea (半平面交求多边形中可以放入最大的圆的半径)
- 打开API的新大门
- 【编译原理】语法分析(二)
- 比特币基本术语快速检索
- [练习][bzoj2783]二分+倍增 树
- leetcode题解-354. Russian Doll Envelopes
- python爬虫案例——百度贴吧数据采集
- Spring框架之jdbc Template 以及事物
- 架构 理论 定律 总结
- MySQL安装与配置 (绿色版不能安装的情况)
- 提取其他app中的资源文件。
- jQuery的淡入淡出
- TensorFlow -2-Ops-1