数列
提交文件:sequence.pas/c/cpp
输入文件:sequence.in
输出文件:sequence.out
问题描述:
把一个正整数分成一列连续的正整数之和。这个数列必须包含至少两个正整数。你需要求出这个数列的最小长度。如果这个数列不存在则输出-1。
输入格式:
每行包含一个正整数n。
每个文件包含多行,读入直到文件结束。
输出格式:
对于每个n,输出一行,为这个数列的最小长度。
第一行是两个整数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。
数据范围:
对于所有数据,n≤263。
这个是JLOI2012的T1,发出来仅为了试题完整
=============================================================================================
在这个问题中,给定一个值S和一棵树。在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。
第一行是两个整数N和S,其中N是树的节点数。
第二行是N个正整数,第i个整数表示节点i的正整数。
接下来的N-1行每行是2个整数x和y,表示y是x的儿子。
对于100%数据,N≤100000,所有权值以及S都不超过1000
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
using namespace std;
set<int> st;
vector<int> e[100005];
int n,s,a[100005],in[100005],sum[100005],ans;
void dfs(int u)
{
if(st.find(sum[u]-s)!=st.end())
ans++;
st.insert(sum[u]);
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i];
sum[v]=sum[u]+a[v];
dfs(v);
}
st.erase(sum[u]);
}
int main()
{
int x,y;
scanf("%d%d",&n,&s);
st.insert(0);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
e[x].push_back(y);
in[y]++;
}
int root;
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
root=i;
break;
}
}
sum[root]=a[root];
dfs(root);
printf("%d\n",ans);
return 0;
}