zoukankan      html  css  js  c++  java
  • 【DP】【P5007】 DDOSvoid 的疑惑

    Description

    给定一棵以 1 为根的有根树,定义树的一个毒瘤集为一个集合,并且集合中任意两个元素之间不存在祖先与后代关系。

    定义一个毒瘤集的毒瘤指数为集合内所有元素的价值之和

    要求给定树的所有毒瘤集的毒瘤指数之和,答案对 100000007 取模。

    但这个问题太难了,所以我们考虑化简。

    因为点的编号跟它毒瘤指数密切相关,所以我们将会再给出一个整数 T,T = 1 表示 i 号点的毒瘤指数为 i,T = 0,表示所有点的毒瘤指数都是 1

    Input

    第一行两个整数 n、T,表示这棵树有 n 个节点。

    接下来 n -1 行,每行两个整数 x 和 y,表示有一条边,连接 x 和 y。

    Output

    输出一个整数,表示答案。

    Hint

    (Forall:)

    (0~leq~n~leq~10^6~,~T~leq~1)

    Solution

    数数题,考虑DP。

    (f_u)是以(u)为根的子树,先考虑 (T~=~0) 的情况

    当点(u)只有两个儿子 (v_1~,~v_2) 的时候,显然 (f_u~=~f_{v_1}~+~f_{v_2}~+~f_{v_1}~ imes~f_{v_2}~+~1)

    考虑(u)有多个儿子的时候也类似,设 (g_j) 为考虑点 (u) 的前(j)个子树的集合数,于是

    (g_j~=~g_{j-1}~ imes~f_v~+~g_j~+~f_v)

    考虑 (T~ eq~0) 的情况

    (f_u) 为以 (u) 为根的ans,(g_u) 为以 (u) 为根的集合个数

    [f_u~=~f_v~ imes~g_u~+~f_u~ imes~g_v~+~f_u~+f_v ]

    [g_u~=~g_u~+~g_v~+~g_u~ imes~g_v ]

    复杂度 (O(n))听说有人用nlogn水过去了?

    Code

    #include <cstdio>
    #ifdef ONLINE_JUDGE
    #define freopen(a, b, c)
    #endif
    #define rg register
    #define ci const int
    #define cl const long long
    
    typedef long long int ll;
    
    namespace IPT {
    	const int L = 1000000;
    	char buf[L], *front=buf, *end=buf;
    	char GetChar() {
    		if (front == end) {
    			end = buf + fread(front = buf, 1, L, stdin);
    			if (front == end) return -1;
    		}
    		return *(front++);
    	}
    }
    
    template <typename T>
    inline void qr(T &x) {
    	rg char ch = IPT::GetChar(), lst = ' ';
    	while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
    	while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
    	if (lst == '-') x = -x;
    }
    
    template <typename T>
    inline void ReadDb(T &x) {
    	rg char ch = IPT::GetChar(), lst = ' ';
    	while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
    	while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
    	if (ch == '.') {
    		ch = IPT::GetChar();
    		double base = 1;
    		while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
    	}
    	if (lst == '-') x = -x;
    }
    
    namespace OPT {
    	char buf[120];
    }
    
    template <typename T>
    inline void qw(T x, const char aft, const bool pt) {
    	if (x < 0) {x = -x, putchar('-');}
    	rg int top=0;
    	do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
    	while (top) putchar(OPT::buf[top--]);
    	if (pt) putchar(aft);
    }
    
    const int maxn = 1000010;
    const int maxm = 2000010;
    const int MOD = 100000007;
    
    struct Edge {
    	int to, nxt;
    };
    Edge edge[maxm]; int hd[maxn], ecnt = 1;
    inline void cont(ci from, ci to) {
    	Edge &e = edge[++ecnt];
    	e.to = to; e.nxt = hd[from]; hd[from] = ecnt;
    }
    
    int n, t;
    int MU[maxn], frog[maxn], gorf[maxn];
    
    void reading();
    void dfs(ci, ci);
    
    int main() {
    	freopen("1.in", "r", stdin);
    	qr(n); qr(t);
    	if (t) {
    		for (rg int i = 1; i <= n; ++i) MU[i] = i;
    	} else {
    		for (rg int i = 1; i <= n; ++i) MU[i] = 1;
    	}
    	reading();
    	dfs(1, 0); qw(frog[1], '
    ', true);
    	return 0;
    }
    
    void reading() {
    	int a, b;
    	for (rg int i = 1; i < n; ++i) {
    		a = b = 0; qr(a); qr(b);
    		cont(a, b); cont(b, a);
    	}
    }
    
    void dfs(ci u, ci pree) {
    	for (int i = hd[u]; i; i = edge[i].nxt) if (i != pree) {
    		int &to = edge[i].to;
    		dfs(to, i ^ 1);
    		frog[u] = (1ll * frog[to] * gorf[u] % MOD + 1ll * frog[u] * gorf[to] % MOD + frog[to] + frog[u]) % MOD;
    		gorf[u] = (1ll * gorf[u] * gorf[to] % MOD + gorf[to] + gorf[u]) % MOD;
    	}
    	frog[u] = (frog[u] + MU[u]) % MOD;
    	gorf[u] = (gorf[u] + 1) % MOD;
    }
    

    Summary

    这是一类非常经典的求树上方案数的题目,一般这类题目的解决方法是使用另一个数组表示“当前已经枚举到的”某些值,每枚举一个儿子单独计算贡献。

  • 相关阅读:
    放弃模拟器,安卓手机WiFi投屏到Ubuntu
    在Ubuntu中使用多显示器远程window主机
    完全卸载visual studio及其组件
    使用defineProperty实现自定义setter, 简化前端Angular的重构工作
    数字图像基础
    Python的文本和字节序列
    机器学习开发流程基础
    深度学习之新闻多分类问题
    深度学习之电影二分类的情感问题
    Chrome89针对sessionStorage的更新导致数据共享问题
  • 原文地址:https://www.cnblogs.com/yifusuyi/p/10087153.html
Copyright © 2011-2022 走看看