D. Valid Sets

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

As you know, an undirected connected graph with n nodes and n - 1 edges is called a tree. You are given an integer d and a tree consisting of n nodes. Each node i has a value ai associated with it.

We call a set S of tree nodes valid if following conditions are satisfied:

S is non-empty.
S is connected. In other words, if nodes u and v are in S, then all nodes lying on the simple path between u and v should also be presented in S.
.

Your task is to count the number of valid sets. Since the result can be very large, you must print its remainder modulo 1000000007 (109 + 7).

Input

The first line contains two space-separated integers d (0 ≤ d ≤ 2000) and n (1 ≤ n ≤ 2000).

The second line contains n space-separated positive integers a1, a2, ..., an(1 ≤ ai ≤ 2000).

Then the next n - 1 line each contain pair of integers u and v (1 ≤ u, v ≤ n) denoting that there is an edge between u and v. It is guaranteed that these edges form a tree.

Output

Print the number of valid sets modulo 1000000007.

Examples

Input

Copy

1 4
2 1 3 2
1 2
1 3
3 4

Output

8

Input

Copy

0 3
1 2 3
1 2
2 3

Output

3

Input

Copy

4 8
7 8 7 5 4 6 4 10
1 6
1 2
5 8
1 3
3 5
6 7
3 4

Output

41

Note

In the first sample, there are exactly 8 valid sets: {1}, {2}, {3}, {4}, {1, 2}, {1, 3}, {3, 4} and {1, 3, 4}. Set {1, 2, 3, 4} is not valid, because the third condition isn't satisfied. Set {1, 4} satisfies the third condition, but conflicts with the second condition.

题解

直接统计不好统计,所以考虑把方案分类。
按照最大值点对方案分类,枚举一个最大值点,让这一个点在方案中,这样就确定了方案能包含的连通块。
设\(dp[i]\)表示一定包含i这个点且i这个点是方案中权值最大的点的方案,有
\[dp[i] = \prod (dp[son_i] + 1)\]

这样会计算重。因为最大值点所确定的连通块里,可能有多个与最大值点权值相同的点,每个点都会算一遍。
只算一个,然后乘以连通的相同值点的个数?
不!别忘了我们\(dp\)的时候,要求选定的点必须在方案中。必定包含不同的相同最大权值点的方案并不是一一对应的。
怎么办?
继续把方案分类。
在这个包含多个最大值点的极大连通块里,设有\(k\)个相同的最大值点。
设最大的相同点编号为\(x\),\(dp\)必定包含点x的集合就行了。
这就相当于,我们只走比他编号小的相同权值的点。

两次使用最大值分类方案的神题Orz
被long long 和 MOD卡了两次。。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
inline long long max(long long a, long long b){return a > b ? a : b;}
inline long long min(long long a, long long b){return a < b ? a : b;}
inline long long abs(long long x){return x < 0 ? -x : x;}
inline void swap(long long &x, long long &y){long long tmp = x;x = y;y = tmp;}
inline void read(long long &x)
{x = 0;char ch = getchar(), c = ch;while(ch < '0' || ch > '9') c = ch, ch = getchar();while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();if(c == '-') x = -x;
}
const long long INF = 0x3f3f3f3f;
const long long MAXN = 2000 + 10;
const long long MOD = 1000000007;
struct Edge
{long long u,v,nxt;Edge(long long _u, long long _v, long long _nxt){u = _u, v  =_v, nxt = _nxt;}Edge(){}
}edge[MAXN << 1];
long long head[MAXN], cnt, n, val[MAXN], d, dp[MAXN], ans;
inline void insert(long long a, long long b)
{edge[++ cnt] = Edge(a, b, head[a]), head[a] = cnt;
}
void dfs(long long x, long long pre, long long root)
{dp[x] = 1;for(long long pos = head[x];pos;pos = edge[pos].nxt){long long v = edge[pos].v;if(v == pre || val[root] - val[v] < 0 || val[root] - val[v] > d || (val[v] == val[root] && v > root)) continue;dfs(v, x, root);dp[x] *= (dp[v] + 1), dp[x] %= MOD;}
}
int main()
{read(d), read(n);for(long long i = 1;i <= n;++ i) read(val[i]);for(long long i = 1;i < n;++ i){long long tmp1, tmp2;read(tmp1), read(tmp2);insert(tmp1, tmp2), insert(tmp2, tmp1);}for(long long i = 1;i <= n;++ i){memset(dp, 0, sizeof(dp));dfs(i, -1, i);ans += dp[i] % MOD;if(ans >= MOD) ans -= MOD;}printf("%I64d", ans);return 0;
}

转载于:https://www.cnblogs.com/huibixiaoxing/p/8535927.html

Codeforces 486D. Valid Sets相关推荐

  1. Codeforces 486D D. Valid Sets

    http://codeforces.com/contest/486/problem/D 题意:给定一棵树,点上有权值,以及d,要求有多少种联通块满足最大值减最小值小于等于d. 思路:枚举i作为最大的点 ...

  2. CodeForces - 103E Buying Sets(最小权闭合子图)

    题目链接:点击查看 题目大意:给出n个数列集合,每个集合都有一个权值,现在要求从中选出k个集合(k可以为0),要求满足: 权值和最小 k个集合取并集后的集合大小等于k 题目要求输出最小权值和 题目分析 ...

  3. CodeForces - 468B Two Sets(并查集+思维)

    题目链接:点击查看 题目大意:现在给出两个集合A和B,再给出两个数a和b,现在规定在集合A中的数x必须满足x和a-x同时在集合a中,而在集合B中的数x也同样需要满足x和b-x同时在集合B中,现在给出一 ...

  4. Codeforces Round #277 (Div. 2) 题解

    Codeforces Round #277 (Div. 2) A. Calculating Function time limit per test 1 second memory limit per ...

  5. Codeforces Round #277(Div 2) A、B、C、D、E题解

    转载请注明出处: http://www.cnblogs.com/fraud/           --by fraud A. Calculating Function 水题,判个奇偶即可 1 #inc ...

  6. 出现字迹模糊迹象_改变迹象:如何使用动态编程解决竞争性编程问题

    出现字迹模糊迹象 by Sachin Malhotra 由Sachin Malhotra 改变迹象:如何使用动态编程解决竞争性编程问题 (Change the signs: how to use dy ...

  7. Pytorch笔记-6

    Text Classification with the torchtext library 本教程,我们将展示如何使用torchtext库,构建文本分类分析用的数据集.用户将能灵活做以下几项: Ac ...

  8. 使用python和opencv构建集合求解器

    Have you ever played SET? SET is a game in which players race to identify patterns of three cards - ...

  9. codeforces B. Eight Point Sets 解题报告

    题目链接:http://codeforces.com/problemset/problem/334/B 一开始看到题目,有点怯,理解了题目后,其实并不难.这句话是突破口 three distinct ...

最新文章

  1. N4 接口解耦的可行性试验
  2. SSH 安全性和配置入门
  3. java json相加_JAVA,当某个json数据中一个字段与另一个json数据中的字段值相同时,对两个json进行合并且相加,...
  4. 列表字符串集合字典的常见方法
  5. python医学应用_数据分析工具鄙视链:Python、R语言是老大,Excel只能称小弟?
  6. 会议交流 | CCKS2020 第十四届全国知识图谱与语义计算大会
  7. 大话php设计模式视频,大话PHP设计模式
  8. [转载] Java 方法(方法重载)与数组
  9. 大数据量下求均值的方法
  10. cmake安装及下载
  11. 祝贺MindV进入香港国际软件大奖赛100强
  12. 产品经理入门知识梳理
  13. Windows远程桌面使用本地USB打印机
  14. 多目标跟踪算法SORT
  15. win10wifi开关自动弹回_win10突然搜不到wifi了,这个开关点不动,点了会自动变回去...
  16. matlab计算概率分布,Matlab中的离散概率分布计算
  17. 注意!这13件事会毁掉你的信用,千万别做!
  18. 反编译获取小程序源码
  19. web自动化(鼠标、键盘操作)
  20. 神威 计算机 应用,Gromacs在神威蓝光超级计算机上的部署和应用(2)

热门文章

  1. Android Stdio换源以及配置项目
  2. python furl模块 网址修改 参数解析
  3. DataNumen DWG Recovery中文版
  4. 编程微刊第五期文章汇总(2018.5)
  5. Optional变量初学者指南
  6. 第二期冲刺站立会议个人博客15(2016/6/08)
  7. oracle随机取数据
  8. Django之路--第一篇
  9. JSP学习笔记(一):JSP语法和指令
  10. 解决查看框架源码时 class file editor source not found