Loading...
6/24/2025
リンク 長さの整数列とが与えられるので、以下の式ををmod 998で求めて下さい。
とりあえず与えられた式を理解しやすいように書き換えると、
という3重シグマの形になる。が、一番内側のシグマについては区間和を表しているので、累積和を用いることで容易に外せる。数列を, とすると、
となる。どう考えても乗の部分が厄介なので、二項展開1を用いてこれを外すと、以下のようになる。
3重シグマとなったが、これらを交換しても答えは変わらない。また、シグマから外側に出せるものは出してしまうことにする。これらを適用すると、式は以下のように変形できる。
ここで、はの累積和を前計算しておくことによって、各に対してで計算ができる。よって全体でで解くことが可能で、この問題の制約下では十分高速になる。
using mint = modint998244353; mint ncr(int n, int r) { mint res = 1; rep(i,r) { res *= (n-i); } rep(i,r) { res /= (i+1); } return res; } void solve() { int n, k; cin >> n >> k; auto a = i64_vec_IN(n); vector<mint> csum(n+1, 0); rep(i,n) csum[i+1] = csum[i] + a[i]; vector<vector<mint>> ccsum(k+1, vector<mint>(n+2, 0)); rep(p, k+1) { rep(i, n+1) { ccsum[p][i+1] = ccsum[p][i] + csum[i].pow(p); } } mint ans = 0; rep(p,k+1){ mint s = 0; rep(l,n) { s += (csum[l] * (-1)).pow(p) * (ccsum[k-p][n+1] - ccsum[k-p][l+1]); } ans += s * ncr(k,p); } cout << ans.val() << ' '; }