1.林下风气
(lkf)
【问题描述】
里口福因有林下风气,带领全国各地高校掀起了一股AK风,大家都十分痴迷于AK。里口福为了打击大家的自信心,出了一道自以为十分困难的题目。
里口福有一棵树,第i个节点上有点权ai,他的问题就是这棵树中有多少个不同的连通块满足连通块的最大值与最小值之差=k,两个连通块不同当且仅当至少存在一个节点在一个连通块中出现而另一个连通块中没有出现。
痴迷于AK的你马上接下这道题目,在里口福狂妄的笑声中,你切掉这道题的决心更加坚定了,现在就差你的代码了。
【输入】
第一行两个整数n,k,表示树的大小以及题目中的k。
第二行n个整数,第i个整数表示ai。
接下来n-1行,每行两个整数x,y表示树边(x,y)。
【输出】
一行一个整数,表示答案,答案对19260817取模。
【样例输入】
5 3
1 2 3 4 5
1 2
1 3
2 4
2 5
【样例输出】
4
【数据范围与约定】
对于30%的数据,n<=22
对于另外20%的数据,树是一条链
对于另外20%的数据,ai只有0和1两种
对于100%的数据,N<=3333,0<=ai<=N,K>=0
至于转移方程看代码吧,建议粘贴到dev里面看
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #define N 50000 5 using namespace std; 6 const long long mod=19260817; 7 long long G[N][2][2]; 8 long long f[N][2][2]; 9 long long val[N],fa[N]; 10 long long Ans=0; 11 struct node { 12 long long u,v; 13 } e[N]; 14 long long first[N],nxt[N],cnt; 15 long long n,k; 16 void add(long long u,long long v) { 17 e[++cnt].u=u; 18 e[cnt].v=v; 19 nxt[cnt]=first[u]; 20 first[u]=cnt; 21 } 22 void DP(long long x,long long max0) { 23 long long min0=max0-k; 24 f[x][0][0]=f[x][0][1]=f[x][1][0]=f[x][1][1]=0; 25 if(val[x]==max0&&val[x]!=min0)f[x][1][0]=1; 26 if(val[x]==min0&&val[x]!=max0)f[x][0][1]=1; 27 if(val[x]==min0&&val[x]==max0)f[x][1][1]=1; 28 if(val[x]>min0&&val[x]<max0)f[x][0][0]=1; 29 for(long long i=first[x]; i; i=nxt[i]) { 30 long long v=e[i].v; 31 if(v!=fa[x]) { 32 fa[v]=x; 33 DP(v,max0); 34 G[x][1][1]=f[x][1][1],G[x][1][0]=f[x][1][0],G[x][0][1]=f[x][0][1],G[x][0][0]=f[x][0][0]; 35 f[x][1][1]+=G[x][1][1]*(f[v][0][0]+f[v][0][1]+f[v][1][0]+f[v][1][1])+G[x][0][1]*(f[v][1][1]+f[v][1][0])+G[x][1][0]*(f[v][0][1]+f[v][1][1])+G[x][0][0]*f[v][1][1]; 36 f[x][1][0]+=G[x][1][0]*(f[v][1][0]+f[v][0][0])+G[x][0][0]*f[v][1][0]; 37 f[x][0][1]+=G[x][0][1]*(f[v][0][0]+f[v][0][1])+G[x][0][0]*f[v][0][1]; 38 f[x][0][0]+=G[x][0][0]*f[v][0][0]; 39 for(long long i=0;i<=1;i++)for(long long j=0;j<=1;j++)f[x][i][j]%=mod; 40 } 41 42 } 43 Ans+=f[x][1][1]; 44 Ans%=mod; 45 return; 46 } 47 int main() { 48 cin>>n>>k; 49 long long max0=0,min0=99999; 50 for(long long i=1; i<=n; i++) { 51 cin>>val[i]; 52 max0=max(max0,val[i]); 53 min0=min(min0,val[i]); 54 } 55 for(long long i=1; i<n; i++) { 56 long long u,v; 57 cin>>u>>v; 58 add(u,v); 59 add(v,u); 60 } 61 for(long long i=min0+k; i<=max0; i++) { 62 DP(1,i); 63 Ans%=mod; 64 } 65 cout<<Ans; 66 return 0; 67 }
over