15.css文字屬性-text屬性-font屬性
阿新 • • 發佈:2021-12-20
菜的真實
C沒看清楚資料範圍炸了兩發血虧
D用二項式定理展開一下就是個很naive的東西了
後兩題比較有意思
E - Medals
首先可以發現天數的上限是\(2*n*1e5\)
顯然可以二分答案
先考慮如何建圖
左邊是員工,右邊是天數,根據\(Hall\)定理我們知道,對於左邊的每個子集
\(G\),都要滿足右邊的連的點集\(|T|\ge |G|\)
放到這題,拓展一下,把每個員工拆成\(k\)個,就相當於是\(k|G|\le |T|\)
然後把每一天來的員工求出來,做個高維字尾和即可
code:
#include<bits/stdc++.h> using namespace std; const int N = (1 << 18) + 5; int f[N], s[20000050], a[21], n, k, cnt[N]; int check(int mid) { int lim = (1 << n); for(int S = 0; S < lim; S ++) f[S] = 0; for(int i = 1; i <= mid; i ++) f[lim - 1] ++, f[(lim - 1) ^ s[i]] --; //for(int S = 0; S < lim; S ++) printf("%d ", f[S]); printf(" %d\n", mid); for(int i = 0; i < n; i ++) for(int S = 0; S < lim; S ++) if(S & (1 << i)) f[S ^ (1 << i)] += f[S]; //for(int S = 0; S < lim; S ++) printf("%d ", f[S]); printf("\n"); for(int S = 0; S < lim; S ++) { if(f[S] < cnt[S] * k) return 0; } return 1; } int main() { scanf("%d%d", &n, &k); for(int i = 1; i <= n; i ++) scanf("%d", &a[i]); int lim = 2 * n * 100000 + 1; for(int i = 1; i <= lim; i ++) for(int j = 1; j <= n; j ++) { if((i - 1) % (2 * a[j]) + 1 <= a[j]) { s[i] |= (1 << (j - 1)); } } for(int i = 1; i < (1 << n); i ++) cnt[i] = cnt[i >> 1] + (i & 1); int l = 0, r = lim; // check(10); while(l + 1 < r) { int mid = (l + r) >> 1; if(check(mid)) r = mid; else l = mid; } printf("%d", r); return 0; }
F - Figures
好題,個人感覺並不比E簡單
首先要知道一點,對於一個每個點度數是確定的,它的生成樹數量是
\[(n-2)!\prod \frac{1}{(in[i]-1)!} \]通過\(prufer\)序列可以輕鬆得知
對於這題,因為它有有個\(d_i\)
所以我們這條式子應變成
\[(n-2)!\prod \frac{d_i^{\underline{in[i]}}}{(in[i]-1)!} \]我們考慮生成函式
設\(\large f_i(x)=\sum\limits_{j=0}^{d_i-1} \frac{d_i^{\underline{j+1}}}{j!}x^j\)
\(\large =\sum\limits_{j=0}^{d_i-1} \frac{d_i!}{j!(d_i-j-1)!}x^j\)
\(\large =d_i\sum\limits_{j=0}^{d_i-1} \frac{(d_i-1)!}{j!(d_i-j-1)!}x^j\)
\(\large =d_i\sum\limits_{j=0}^{d_i-1} \binom{d_i-1}{j}x^j\)
\(\large = d_i(x+1)^{d_i-1}\)
於是上面那條式子可以表示為
\(\large (n-2)! [x^{n-2}]\prod_{i=1} f_i(x)\)
\(=\large (n-2)! [x^{n-2}] \prod_{i=1}d_i(x+1)^{d_i-1}\)
\(=\large (n-2)! \prod_{i=1}d_i \ \ [x^{n-2}] (x+1)^{\sum d_i-1}\)
直接計算即可
code:
#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
int n, sum, x;
int main() {
scanf("%d", &n);
int ans = 1;
for(int i = 1; i <= n; i ++) {
scanf("%d", &x); sum += x - 1; sum %= mod;
ans = 1ll * ans * x % mod;
}
for(int i = 0; i < n - 2; i ++) ans = 1ll * ans * (sum - i) % mod;
printf("%d", ans);
return 0;
}