0501模擬賽

A

在這裏插入圖片描述
在這裏插入圖片描述
考試寫了暴力ntt走人。
在這裏插入圖片描述

#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
int p[105], t[50000005];
int n, k, x, s, ans;
inline int qpow(int a, int b) {
	int re = 1;
	for(; b; b>>=1, a=1ll*a*a%mod)if(b&1)re=1ll*re*a%mod;
	return re;
}
int main () {
	scanf("%d%d%d", &n, &k, &x);
	for(int i = 0; i <= k; ++i) scanf("%d", &p[i]), s += p[i];
	s = qpow(s, mod-2);
	for(int i = 0; i <= k; ++i) p[i] = 1ll*p[i]*s%mod;
	t[0] = qpow(p[0], n); s = 0;
	for(int i = 0; i < x; ++i) {
		(s += t[i]) %= mod;
		ans = (ans + 1ll*i*t[i]) % mod;
		for(int j = max(0, i-k+1); j <= i; ++j)
			t[i+1] = (t[i+1] + 1ll*t[j]*(i-j+1)%mod*p[i-j+1]%mod*n - 1ll*t[j]*j%mod*p[i-j+1]%mod) % mod;
		t[i+1] = 1ll * t[i+1] * qpow(1ll*(i+1)*p[0]%mod, mod-2) % mod;
	}
	ans = ((ans + (1ll-s)*x) % mod + mod) % mod;
	printf("%d\n", ans);
}

B

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
const int mod = 998244353;
const int inv2 = 998244354/2;
int n, q, fac[MAXN], inv[MAXN], pw2[MAXN];
void pre(int N) {
	*fac = *inv = fac[1] = inv[1] = 1;
	for(int i = 2; i <= N; ++i) fac[i] = 1ll*fac[i-1]*i%mod, inv[i] = 1ll*(mod-mod/i)*inv[mod%i]%mod;
	for(int i = 2; i <= N; ++i) inv[i] = 1ll*inv[i-1]*inv[i]%mod;
	pw2[0] = 1; for(int i = 1; i <= N; ++i) pw2[i] = 1ll*pw2[i-1]*inv2%mod;
}
inline int C(int n, int m) { return m < 0 || m > n ? 0 : 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod; }
int id[MAXN], tot, f[705][MAXN];
int cal(int x, int l, int r) { //(l, r]
	if(!id[x]) {
		id[x] = ++tot;
		for(int i = 1; i <= n<<1; ++i)
			f[tot][i] = (f[tot][i-1] + 1ll * C(i-1, x-1) * pw2[i]) % mod;
	}
	return l < r ? (f[id[x]][r]-f[id[x]][l]) % mod : 0;
}
int main () {
	scanf("%d%d", &n, &q); pre(n<<1);
	int k, x, ans, lst;
	while(q--) {
		scanf("%d", &k); ans = lst = 0;
		for(int i = 0; i < k; ++i)
			scanf("%d", &x), ans = (ans + 1ll*cal(n, lst-i, x-i-1)*pw2[i]) % mod, lst = x;
		if(lst < n<<1) {
			ans = (ans + 1ll * C(lst-k, n-k) * pw2[lst]) % mod;
			if(k < n)
				ans = (ans + 1ll*(cal(n, lst-k, (n<<1)-k-1) + cal(n-k, lst-k, (n<<1)-k-1))%mod * pw2[k]) % mod;
		}
		printf("%d\n", (2*ans%mod+mod)%mod);
	}
}

C

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
本來要寫一般圖匹配什麼帶花樹。但是我不會)結果暴力建邊匈牙利或者隨機匹配(不隨機)都能過。。。

代碼:(不是我的)

#include<bits/stdc++.h>
#define maxn 200005
using namespace std;

int n,K,bit[maxn],mat[maxn];
vector<int>G[20];
vector<vector<int> >ans;

void print(int x){
	for(int i=0;i<n;i++) if(x>>i&1) putchar('a'+i);
}

int main(){
	
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	
	scanf("%d%d",&n,&K);
	for(int i=1;i<(1<<n);i++){
		bit[i] = bit[i>>1] + (i&1);
		G[bit[i]] .push_back(i);
	}
	for(int i=0;i<=K-i;i++){
		set<int>st;
		for(int j=0;j<G[i].size();j++)
			st.insert(G[i][j]);
	//	random_shuffle(G[K-i].begin(),G[K-i].end());
		int l = 0;
		for(int u;!st.empty();){
			if(i == K-i && st.size() == 1) break;
			u=*st.begin();
			for(;;l++){
				if(l == G[K-i].size()) l = 0;
				if((G[K-i][l] & u) == 0){
					int v = G[K-i][l];
					if(mat[v]) mat[mat[v]] = 0 , st.insert(mat[v]);
					else st.erase(v);
					mat[u] = v , mat[v] = u;
					st.erase(u);
					l++;
					break;
				}
			}
		}
	}
	for(int i=1;i<(1<<n);i++) if(bit[i] <= K){
		if(mat[i]){
			if(mat[i] > i){
				vector<int>r;
				r.push_back(i),r.push_back(mat[i]);
				ans.push_back(r);
			}
		}
		else{
			vector<int>r;
			r.push_back(i);
			ans.push_back(r);
		}
	}
	printf("%d\n",ans.size());
	for(int i=0;i<ans.size();i++){
		printf("%d",ans[i].size());
		for(int j=0;j<ans[i].size();j++)
			putchar(' '),print(ans[i][j]);
		puts("");
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章