首页 > 其他分享 >AtCoder Regular Contest 115 D Odd Degree

AtCoder Regular Contest 115 D Odd Degree

时间:2023-04-22 16:11:20浏览次数:55  
标签:AtCoder Degree Contest int ll long 奇度 maxn

洛谷传送门

AtCoder 传送门

若连通块是一棵树,考虑钦定 \(k\) 个点为奇度点,方案数为 \(\binom{n}{k}\)。对于叶子,如果它是奇度点,那么连向它父亲的边要保留,否则不保留。这样自底向上考虑,任意一条边的保留情况都可以唯一确定,所以最后方案数就是 \(\binom{n}{k}\)。

若连通块存在环,仍然钦定 \(k\) 个点为奇度点。考虑随便拎出一棵生成树,非树边选可不选;确定了非树边的状态,就和树的情况一样了。设连通块边数为 \(m\),最后方案数就是 \(2^{m-n+1} \binom{n}{k}\)。

多个连通块的情况,考虑背包 dp,设 \(f_{i,j}\) 为前 \(i\) 个连通块,选了 \(j\) 个奇度点的方案数。转移枚举第 \(i\) 个连通块钦定 \(k\) 个奇度点(\(k\) 为偶数)即可。

时间复杂度 \(O(n^2)\)。

code
// Problem: D - Odd Degree
// Contest: AtCoder - AtCoder Regular Contest 115
// URL: https://atcoder.jp/contests/arc115/tasks/arc115_d
// Memory Limit: 1024 MB
// Time Limit: 2000 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 long double ldb;
typedef pair<int, int> pii;

const int maxn = 5050;
const int N = 5000;
const ll mod = 998244353;

inline ll qpow(ll b, ll p) {
	ll res = 1;
	while (p) {
		if (p & 1) {
			res = res * b % mod;
		}
		b = b * b % mod;
		p >>= 1;
	}
	return res;
}

int n, m, a[maxn], sz[maxn], fa[maxn];
ll fac[maxn], ifac[maxn], pw[maxn], f[maxn][maxn];
pii E[maxn];

int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

inline void merge(int x, int y) {
	x = find(x);
	y = find(y);
	if (x != y) {
		fa[x] = y;
		sz[y] += sz[x];
	}
}

void init() {
	pw[0] = fac[0] = 1;
	for (int i = 1; i <= N; ++i) {
		pw[i] = pw[i - 1] * 2 % mod;
		fac[i] = fac[i - 1] * i % mod;
	}
	ifac[N] = qpow(fac[N], mod - 2);
	for (int i = N - 1; ~i; --i) {
		ifac[i] = ifac[i + 1] * (i + 1) % mod;
	}
}

inline ll C(ll n, ll m) {
	if (n < m || n < 0 || m < 0) {
		return 0;
	} else {
		return fac[n] * ifac[m] % mod * ifac[n - m] % mod;
	}
}

void solve() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		fa[i] = i;
		sz[i] = 1;
	}
	for (int i = 1; i <= m; ++i) {
		scanf("%d%d", &E[i].fst, &E[i].scd);
		merge(E[i].fst, E[i].scd);
	}
	for (int i = 1; i <= m; ++i) {
		++a[find(E[i].fst)];
	}
	f[0][0] = 1;
	int t = 0;
	for (int i = 1; i <= n; ++i) {
		if (fa[i] != i) {
			continue;
		}
		++t;
		for (int j = 0; j <= n; ++j) {
			for (int k = 0; k <= min(sz[i], j); k += 2) {
				f[t][j] = (f[t][j] + f[t - 1][j - k] * C(sz[i], k) % mod * pw[a[i] - (sz[i] - 1)] % mod) % mod;
			}
		}
	}
	for (int i = 0; i <= n; ++i) {
		printf("%lld\n", f[t][i]);
	}
}

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

标签:AtCoder,Degree,Contest,int,ll,long,奇度,maxn
From: https://www.cnblogs.com/zltzlt-blog/p/17343275.html

相关文章

  • AtCoder Regular Contest 114 F Permutation Division
    洛谷传送门AtCoder传送门这题居然是之前某场模拟赛(contest701)的T1……(@Vidoliga场切但是被卡常/bx)下面记\(m\)为原题面中的\(K\),\(a_i\)为原题面中的\(P_i\)。不难发现后手的策略是把所有段按照段的第一个数从大到小排序接在一起。考虑若\(a_1\lem\),则先手能把所......
  • AtCoder Regular Contest 114 D Moving Pieces on Line
    洛谷传送门AtCoder传送门挺有意思的题。首先显然地,一个棋子不会走回头路。于是一个棋子沿着边走的效果就是区间异或。更进一步,设\(s_i\)为\(i-1\toi\)的边颜色与\(i\toi+1\)的边颜色是否相同(差分),相当于对于每个\(i\)都选择\(s_{a_i}\)和\(s_{x_i}\),将它们异或......
  • 模拟赛 & VP & Contest 记录
    CatOJC140(初中)\(100+93+100+10=303\),Rank1。是个dp场,A题期望dp,B题神奇猜结论,C题换根dp,D题树上博弈dp。A题设\(f_u\)为填满子树\(u\)的期望次数,\(s_u\)为\(u\)子树大小,容易得到\(f_u=f_v+\frac{1}{s_u}\)。B题若\(n\)是偶数,考虑数列里随便取一个数将其......
  • Atcoder Beginner Contest 298---E
    题目:E-UnfairSugoroku(atcoder.jp)分析:这题状态转移方程挺好推的,但是用dp解是我没想到的dp[i][j][0]表示T在i点,A在j点且轮到T走时赢的概率dp[i][j][1]表示T在i点,A在j点且轮到A走时赢的概率代码:#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#def......
  • AtCoder Regular Contest 109 F 1D Kingdom Builder
    洛谷传送门AtCoder传送门考虑判断一个终止态是否可达。如果只有一个棋子连续段那一定可达;否则就存在\(\ge2\)个连续段。此时把放棋子看成删除,那么限制就是如果删除一个孤立的棋子(两边没有棋子)且还有别的格子有棋子,这个棋子的颜色异于其他连续段的两边棋子的颜色。设第一......
  • AtCoder Beginner Contest 298
    A-JobInterview#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn; strings; cin>>n>>s; if(s.find("x")!=-1){ printf("No\n"); }elseif(s.find("o")==-1){ printf("No......
  • Atcoder Regular Contest 118 E - Avoid Permutations(容斥+DP)
    挺套路的DP。第一步是显然的:转换贡献体,DP一条从\((0,0)\)到\((n+1,n+1)\)的路径,然后计算有多少个排列满足这条路径不经过任何一个\((i,p_i)\)。正着统计肯定不好求,考虑容斥。即我们钦定一些路径上的点,满足这些点必须对应某个\((i,p_i)\),然后计算有多少个\(p\)符合这个......
  • Contest 23-04-18
    #D.糖果镇思路\(m=3\)时整个路径有两个拐点,分别是\(m=1\tom=2,m=2\tom=3\)设拐点\(1\)在第\(i\)列,拐点\(2\)在第\(j\)列,则路径上的数字总和为\((front[1][i])+(front[2][j]-front[2][i-1])+(back[j])\)(\(front[i][j]\)表示第i行\(1\toj\)的前缀和,\(back[j]\)表......
  • AtCoder Regular Contest 109 E 1D Reversi Builder
    洛谷传送门AtCoder传送门考虑固定\(s\)和每个格子的颜色,最终有多少个石子被染黑。结论:任何时刻只有不多于两个极大同色连通块。证明:设\([x,y]\)为当前的黑连通块,\([y+1,z]\)为白连通块。如果下一次染\(x-1\),若\(x-1\)为白,则\([x-1,z]\)都被染为白;否则\(x-1\)被......
  • AtCoder Regular Contest 109 D L
    洛谷传送门AtCoder传送门这种题根本做不出来……考虑一个L形怎么方便地表示出来。可以发现对于组成L形的三个点\((x_1,y_1),(x_2,y_2),(x_3,y_3)\),只要知道\(x=x_1+x_2+x_3\)和\(y=y_1+y_2+y_3\),就能确定三个坐标。证明是设折点坐标为\((p,q)\),则其余两......