第一行是两个整数N和S,其中N是树的节点数。
第二行是N个正整数,第i个整数表示节点i的正整数。
接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
输出格式:
输出路径节点总和为S的路径数量。
|
输入样例: |
输出样例: |
|
3 3 1 2 3 1 2 1 3 |
2 |
数据范围:
对于30%数据,N≤100;
对于60%数据,N≤1000;
对于100%数据,N≤100000,所有权值以及S都不超过1000。
这个是JLOI2012的T1,发出来仅为了试题完整
=============================================================================================
在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。
第一行是两个整数N和S,其中N是树的节点数。
第二行是N个正整数,第i个整数表示节点i的正整数。
接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
输出路径节点总和为S的路径数量。
对于100%数据,N≤100000,所有权值以及S都不超过1000。
用f[i][j]表示i的第2^j个祖先,可以用倍增法预处理。
对于每一个点,二分第k个祖先,比较两点距离和s的大小。
总的时间复杂度O(nlog^2n)。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 100005
#define inf 1000000000
using namespace std;
struct edge_type
{
int next,to;
}e[maxn];
int a[maxn],d[maxn],dep[maxn],in[maxn],head[maxn],f[maxn][20];
int n,s,x,y,root,ans=0,cnt=0;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
inline void add_edge(int x,int y)
{
e[++cnt]=(edge_type){head[x],y};
head[x]=cnt;
in[y]++;f[y][0]=x;
}
inline void dfs(int x)
{
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
d[y]=d[x]+a[y];dep[y]=dep[x]+1;
dfs(y);
}
}
inline int find(int x,int k)
{
int t=0,p=x;
while (k)
{
if (k&1) p=f[p][t];
t++;k>>=1;
}
return p;
}
inline bool check(int x)
{
int l=0,r=dep[x],mid,tmp;
while (l<=r)
{
mid=(l+r)>>1;
tmp=find(x,mid);
if (d[x]-d[tmp]==s) return true;
else if (d[x]-d[tmp]<s) l=mid+1;
else r=mid-1;
}
return false;
}
int main()
{
n=read();s=read();
F(i,1,n) a[i]=read();
F(i,1,n-1)
{
x=read();y=read();
add_edge(x,y);
}
F(i,1,n) if (!in[i]){root=i;break;}
d[root]=a[root];dep[root]=1;f[root][0]=0;
dfs(root);
for(int j=1;(1<<j)<=n;j++) F(i,1,n) f[i][j]=f[f[i][j-1]][j-1];
F(i,1,n) if (check(i)) ans++;
printf("%d\n",ans);
}
原文:http://blog.csdn.net/aarongzk/article/details/50539142