【題解】ARC124E - Pass to Next
阿新 • • 發佈:2021-10-01
首先我們要求集合中所有方案的代價之和,簡單分析下不難發現,如果每個位置都傳球了,那麼每個位置都少傳一個球的方案一定會被重複統計。
所以答案就是總方案數減去每個位置都至少傳一個球的方案數。
考慮 \(\prod x_i\) 的意義,等價於傳球后從每個人手中拿出一個球的方案數。
因此我們將每個人的球排成一排,顯然對於每個人來說,他可以選擇拿出自己的球,也可以從前面一個人中拿出一個球。需要注意的是自己拿的球一定在前面一個人後面,並且兩人之間存在一個斷點。
所以我們定義狀態 \(f_{i,0/1}\) 表示前 \(i\) 個人,第 \(i\) 個人拿自己/別人的球,前 \((i - 1)\) 個人的方案數。每次欽定 \(f_{1,0/1}\)
這就是計數的第X種方法——組合意義
#define N 300005 int n, a[N], f[N][2]; int g2(int x){ return 1LL * x * (x - 1) % P * ((P + 1) / 2) % P; } int g3(int x){ return 1LL * x * (x - 1) % P * (x - 2) % P * ((P + 1) / 6) % P; } int w2(int x){ return (g2(x) + x) % P; } int w3(int x){ return (g3(x) + g2(x)) % P; } int calc(int st, int op){ memset(f, 0, sizeof(f)); if(!op){ f[1][st] = 1; rep(i, 1, n){ if(a[i] > 0)ad(f[i + 1][0], 1LL * f[i][1] * (a[i] + 1) % P); if(a[i] > 0)ad(f[i + 1][0], 1LL * f[i][0] * w2(a[i]) % P); if(a[i] > 0)ad(f[i + 1][1], 1LL * f[i][1] * w2(a[i]) % P); if(a[i] > 1)ad(f[i + 1][1], 1LL * f[i][0] * w3(a[i]) % P); } return f[n + 1][st]; } f[1][st] = 1; rep(i, 1, n){ if(a[i] > 0)ad(f[i + 1][0], 1LL * f[i][1] * a[i] % P); if(a[i] > 0)ad(f[i + 1][0], 1LL * f[i][0] * g2(a[i]) % P); if(a[i] > 0)ad(f[i + 1][1], 1LL * f[i][1] * w2(a[i]) % P); if(a[i] > 1)ad(f[i + 1][1], 1LL * f[i][0] * w3(a[i]) % P); } return f[n + 1][st]; } int main() { //int T = read();while(T--)solve(); n = read(); rp(i, n) a[i] = read(); //cout << w3(3) << " " << w3(4) << endl; //cout << g3(2) << " " << g3(3) << " " << g3(4) << endl; int ans = (calc(0, 0) + calc(1, 0)) % P; su(ans, (calc(0, 1) + calc(1, 1)) % P); cout << ans << endl; return 0; }