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("");
}
}