CF486D-Valid Sets
题目
给出一个\(n\)个点的树,每个点有权值\(a_i\),再给出一个\(d\),问有多少个非空点集满足:
- 点集在树上构成联通子图
- \[\max _{v\in S}a_v -\min _{v\in S}\le d$$,即集合内权值最大减最小在$d$以内
\]
分析
首先如何求树上联通子图的总数?设\(f_i\)表示包含\(i\)点的联通子图个数,那么有:
\]
即考虑是否包含每个子树中的集合,如果不包含就给其他的乘1,否则就乘上子树中的集合个数。
如果有\(d\)的条件怎么办呢?
为了不算重,我们对每个点\(x\)做树形dp,强制\(a_x\)为权值最小的,那么只进入\(a_x\le a_v\le a_x+d\)的子树进行计算。但这样依然会算重,原因是如果有相同权值的点,那么可能会在这些点都统计到同一个集合。
于是我们给它定序。重复计算其实就是没有一个顺序来区分这些集合。所以当遇到\(a_x=a_v\)的时候,只有\(v>x\)我们才走进去,这样就相当于给集合中相同最小权值的点定序,去除了重复的情况。
代码
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long giant;
int read() {
int x=0,f=1;
char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int maxn=2e3+1;
const int q=1e9+7;
int n,d,a[maxn],f[maxn],ans=0;
vector<int> g[maxn];
inline void add(int x,int y) {g[x].push_back(y);}
inline int Plus(int x,int y) {return ((giant)x+(giant)y)%q;}
inline int Multi(int x,int y) {return (giant)x*y%q;}
void dfs(int x,int fa,int id,int lim) {
int &fx=f[x]=1;
for (int v:g[x]) if (v!=fa && ((lim<a[v] && a[v]<=lim+d) || (lim==a[v] && v>id))) dfs(v,x,id,lim),fx=Multi(f[x],f[v]+1);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
d=read(),n=read();
for (int i=1;i<=n;++i) a[i]=read();
for (int i=1;i<n;++i) {
int x=read(),y=read();
add(x,y),add(y,x);
}
for (int i=1;i<=n;++i) {
memset(f,0,sizeof f);
dfs(i,i,i,a[i]);
ans=Plus(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}
CF486D-Valid Sets的更多相关文章
- Codeforces Round #277 (Div. 2) D. Valid Sets 暴力
D. Valid Sets Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/486/problem ...
- Codeforces Round #277 (Div. 2) D. Valid Sets (DP DFS 思维)
D. Valid Sets time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Codeforces 486D Valid Sets (树型DP)
题目链接 Valid Sets 题目要求我们在一棵树上计符合条件的连通块的个数. 满足该连通块内,点的权值极差小于等于d 树的点数满足 n <= 2000 首先我们先不管这个限制条件,也就是先考 ...
- Codeforces Round #277 (Div. 2) D. Valid Sets DP
D. Valid Sets As you know, an undirected connected graph with n nodes and n - 1 edges is called a ...
- Codeforces 486D. Valid Sets
D. Valid Sets time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Codeforces 486D D. Valid Sets
http://codeforces.com/contest/486/problem/D 题意:给定一棵树,点上有权值,以及d,要求有多少种联通块满足最大值减最小值小于等于d. 思路:枚举i作为最大的点 ...
- Codeforces 486D Valid Sets:Tree dp【n遍O(n)的dp】
题目链接:http://codeforces.com/problemset/problem/486/D 题意: 给你一棵树,n个节点,每个节点的点权为a[i]. 问你有多少个连通子图,使得子图中的ma ...
- 【【henuacm2016级暑期训练】动态规划专题 N】Valid Sets
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 给你一棵树. 让你统计其中子树T的数量. 这个子树T要满足最大值和最小值之差小于等于d 树形DP 可以枚举点root为子树的根. 统 ...
- codeforces 486 D. Valid Sets(树形dp)
题目链接:http://codeforces.com/contest/486/problem/D 题意:给出n个点,还有n-1条边的信息,问这些点共能构成几棵满足要求的树,构成树的条件是. 1)首先这 ...
- 2016 Google code jam 答案
二,RoundC import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundE ...
随机推荐
- 20155321 2016-2017-2 《Java程序设计》第二周学习总结
教材学习内容总结 这星期主要学习了Java语言中的各种运算符以及基本的一些语句,除了个别地方之外大部分和以往C语言学的东西比较相似,在比较中看教材学习比较容易掌握第三章的内容,课后练习的难度也不是很大 ...
- 20145209 实验三 《敏捷开发与XP实践》 实验报告
20145209 实验三 <敏捷开发与XP实践> 实验报告 实验内容 XP基础. XP核心实践. 相关工具. 实验步骤 敏捷开发与XP 1.敏捷开发 敏捷开发(Agile Developm ...
- jdk各种老版本的下载链接
java SE 1.6各个版本 jdk api http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downlo ...
- PostgreSQL的pg_stats学习
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL统计信息索引页 回到顶级页面:PostgreSQL索引页 对于pg_stas,说明文档在这里: http://w ...
- 【转载】OGRE中用到的设计模式
原文:OGRE中用到的设计模式 1. 单例模式(Singleton) 2. 工厂方法(Factory Method) 3. 适配器模式(Adapter) 4. ...
- 【LG3244】[HNOI2015]落忆枫音
题面 洛谷 题解 20pts 枚举每一条边是否在树中即可. 另10pts 我们考虑一张\(DAG\)中构成树的方法数,每个点选一个父亲即可,那么有 \[Ans=\prod_{i=1}^{n} deg_ ...
- DSP28335声音降噪(未完成)
1. 确定使用的模块是Webrtc-NS,采集声音的芯片TLV32AIC23,实际测试发现Webrtc-NS无法使用,所以改成FIR滤波器. 从时域特性上来看,数字滤波器还可以分为有限冲激响应数字滤波 ...
- 一个自己实现的string
最近实现了一个string类,添加了一些c++11元素. 除了基本的构造析构函数,拷贝构造和赋值函数,另外添加移动拷贝和赋值函数.default是一个很方便的特性有木有. //default cons ...
- K-means算法实现
目录 K-means K-means x = xlsread("D:\MatlabData\西瓜数据集.xlsx"); m = length(x); [Idx,C]=kmeans( ...
- [leetcode]三数之和
三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复 ...