首页 > 其他分享 >AtCoder Beginner Contest 207 F Tree Patrolling

AtCoder Beginner Contest 207 F Tree Patrolling

时间:2023-05-11 22:45:36浏览次数:41  
标签:AtCoder typedef Beginner 207 Contest long maxn define

洛谷传送门

AtCoder 传送门

简单树形 dp。

设 \(f_{u,i,p=0/1,q=0/1}\) 为 \(u\) 的子树中被覆盖点数为 \(i\),\(u\) 有没有被覆盖,\(u\) 有没有被选。

转移树形背包合并即可,需要分类讨论。要注意如果 \(u\) 没被覆盖,\(v\) 选了,或者 \(u\) 选了,\(v\) 没被覆盖,被覆盖点数要 \(+1\)。

式子较复杂,具体见代码。

code
// Problem: F - Tree Patrolling
// Contest: AtCoder - AtCoder Beginner Contest 207
// URL: https://atcoder.jp/contests/abc207/tasks/abc207_f
// Memory Limit: 1024 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 2020;
const ll mod = 1000000007;

ll n, f[maxn][maxn][2][2], sz[maxn], head[maxn], len, g[maxn][2], h[maxn][maxn][2];
struct edge {
	int to, next;
} edges[maxn << 1];

inline void add_edge(int u, int v) {
	edges[++len].to = v;
	edges[len].next = head[u];
	head[u] = len;
}

void dfs(int u, int fa) {
	f[u][0][0][0] = f[u][1][1][1] = 1;
	sz[u] = 1;
	for (int i = head[u]; i; i = edges[i].next) {
		int v = edges[i].to;
		if (v == fa) {
			continue;
		}
		dfs(v, u);
		for (int j = 0; j <= sz[u]; ++j) {
			g[j][0] = f[u][j][0][0];
			g[j][1] = f[u][j][1][0];
			f[u][j][0][0] = f[u][j][1][0] = 0;
		}
		for (int j = 0; j <= sz[u]; ++j) {
			for (int k = 0; k <= sz[v]; ++k) {
				for (int x = 0; x <= 1; ++x) {
					for (int y = 0; y <= 1; ++y) {
						if (!x && y) {
							f[u][j + k][0][0] = (f[u][j + k][0][0] + g[j][0] * f[v][k][1][0] % mod) % mod;
							f[u][j + k + 1][1][0] = (f[u][j + k + 1][1][0] + g[j][0] * f[v][k][1][1] % mod) % mod;
						} else {
							f[u][j + k][x | y][0] = (f[u][j + k][x | y][0] + g[j][x] * h[v][k][y] % mod) % mod;
						}
					}
				}
			}
		}
		for (int j = 0; j <= sz[u]; ++j) {
			g[j][0] = f[u][j][0][1];
			g[j][1] = f[u][j][1][1];
			f[u][j][0][1] = f[u][j][1][1] = 0;
		}
		for (int j = 0; j <= sz[u]; ++j) {
			for (int k = 0; k <= sz[v]; ++k) {
				for (int x = 0; x <= 1; ++x) {
					f[u][j + k + (x ^ 1)][1][1] = (f[u][j + k + (x ^ 1)][1][1] + g[j][1] * h[v][k][x] % mod) % mod;
				}
			}
		}
		sz[u] += sz[v];
	}
	for (int i = 0; i <= sz[u]; ++i) {
		h[u][i][0] = (f[u][i][0][0] + f[u][i][0][1]) % mod;
		h[u][i][1] = (f[u][i][1][0] + f[u][i][1][1]) % mod;
	}
}

void solve() {
	scanf("%lld", &n);
	for (int i = 1, u, v; i < n; ++i) {
		scanf("%d%d", &u, &v);
		add_edge(u, v);
		add_edge(v, u);
	}
	dfs(1, -1);
	for (int i = 0; i <= n; ++i) {
		printf("%lld\n", (h[1][i][0] + h[1][i][1]) % mod);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,typedef,Beginner,207,Contest,long,maxn,define
From: https://www.cnblogs.com/zltzlt-blog/p/17392463.html

相关文章

  • AtCoder Beginner Contest 177 F I hate Shortest Path Problem
    洛谷传送门AtCoder传送门设\(f_{i,j}\)为从第\(1\)行到\((i+1,j)\)的最短路。因为我们并不关心最后到达的是哪一个格子,于是强制\(f_{i,j}\)为必须从\((i,j)\)往下走一格到\((i+1,j)\)的最短路。有转移:\[f_{i,r+1}\getsf_{i-1,j}+r+2-j,j\in[l......
  • AtCoder Beginner Contest 152 A-E
    AtCoderBeginnerContest152A-ACorWAvoidsolve(){intn=read(),m=read();puts(n==m?"Yes":"No");}B-ComparingStringsvoidsolve(){intn=read(),m=read();if(m<n)swap(n,m);for(inti=1;i<=m;i++){......
  • AtCoder 好题选做
    AtCoderRegularContest091-F-StrangeNimhttps://atcoder.jp/contests/arc091/tasks/arc091_d清北学堂讲的一道题,我艹感觉这结论很难猜啊。做这种题一定是先写爆搜打表啊,先写了一个博弈论求SG函数:然后发现了一个规律:\(\text{SG}(nk,k)=n\)。还有一个规律:当\(n<k......
  • AtCoder Beginner Contest 298 题解
    题面:https://atcoder.jp/contests/abc298/tasks_printA-JobInterview直接模拟即可。#include<bits/stdc++.h>#include<ext/pb_ds/assoc_container.hpp>#include<ext/pb_ds/tree_policy.hpp>#include<ext/pb_ds/hash_policy.hpp>usingnamespace......
  • AtCoder DP系列刷题记录
    直面自己的弱点。AFrog1简单线性\(\text{dp}\),令\(dp_i\)为跳到第\(i\)块石头的最小花费,易得:\[dp_i+=\min(|a_i-a_{i-1}|,|a_i-a_{i-2}|)\]BFrog2很快就写完了,但是一直调了十分钟,耻辱啊。如果反着跳,第\(i\)根木桩只能从第\(i+1\)或\(i+2\)木桩上跳到,则有:\[d......
  • AtCoder Beginner Contest 234 Ex Enumerate Pairs
    洛谷传送门AtCoder传送门把每个点分到\((\left\lfloor\frac{x}{K}\right\rfloor,\left\lfloor\frac{y}{K}\right\rfloor)\)的正方形内,枚举相邻正方形,计入答案。正确性显然。复杂度证明就是所有每个正方形内距离为\(K\)的点对下界为\(\Omega(n^2)\)。考虑分成四个边长为......
  • AtCoder Beginner Contest 221 F Diameter set
    洛谷传送门AtCoder传送门显然,选出的每两个点都要组成一条直径。还是显然,每条直径的重合部分只可能是一个点或一条边。简单证一下,没有重合显然不可能,重合超过一个点或一条边,直径会更长。进一步发现,设直径点数为\(x\),如果\(x\nmid2\),重合部分是一个点,否则重合部分是一条边......
  • AtCoder Beginner Contest 206(Sponsored by Panasonic)(E,F)
    AtCoderBeginnerContest206(SponsoredbyPanasonic)(E,F)E(容斥,gcd)E这个题大意就是给出一个\(l\)和一个\(r\),寻找满足以下条件的一对数\((x,y)\)的数量\(gcd(x,y)!=1\)\(gcd!=x\)并且\(gcd!=y\)(从这一句我们可以知道\(x\)不可能被\(y\)整除)那么我们可以设\(x\)是\(t\)的倍......
  • AtCoder Beginner Contest 217 G Groups
    洛谷传送门AtCoder传送门不妨钦定组之间的顺序是最小值越小的组越靠前,这样可以给每个组按顺序编号。设\(f_{i,j}\)为考虑了模\(m\)后\(<i\)的数,目前有\(j\)个非空组的方案数。转移就是枚举模\(m=i-1\)的数新开了\(k\)个组,设\(\len\)的数中模\(m=i-1......
  • [AtCoder-AT_ABC070C]题解(C++)
    PartIPreface原题目(Luogu)原题目(AtCoder)PartIISketch给定一个正整数\(N(1\leqN\leq100)\),表示时钟数量。接下来\(N\)行,每行一个正整数\(T_i(1\leqT_i\leq10^{18})\),表示每个时钟旋转\(T_i\)秒后还会回到原来的地方。求出在多少秒之后,所有时钟还会同时......