• CF486D-Valid Sets


    题目

    给出一个(n)个点的树,每个点有权值(a_i),再给出一个(d),问有多少个非空点集满足:

    • 点集在树上构成联通子图
    • [max _{vin S}a_v -min _{vin S}le d$$,即集合内权值最大减最小在$d$以内 ]

    分析

    首先如何求树上联通子图的总数?设(f_i)表示包含(i)点的联通子图个数,那么有:

    [f_x=prod _{(x,v)in E}(f_v+1) ]

    即考虑是否包含每个子树中的集合,如果不包含就给其他的乘1,否则就乘上子树中的集合个数。

    如果有(d)的条件怎么办呢?

    为了不算重,我们对每个点(x)做树形dp,强制(a_x)为权值最小的,那么只进入(a_xle a_vle 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
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    设置Jmeter默认中文页面
    spring boot controller设置 @Transactional 不回滚的解决办法
    SpringBoot事务注解@Transactional
    spring boot @Transactional事物处理
    Spring事务管理中@Transactional
    @Transactional 注解的使用和注意
    spring的@Transactional注解详细用法
    【Developer Log】ProGuard扰码可执行JAR包
    使用Jprofiler+jmeter进行JVM性能调优
    SQL中如何使用EXISTS替代IN
  • 原文地址:https://www.cnblogs.com/owenyu/p/7144699.html
Copyright © 2020-2023  润新知