結果
問題 |
No.1848 Long Prefixes
|
ユーザー |
👑 ![]() |
提出日時 | 2025-04-17 11:05:35 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,732 bytes |
コンパイル時間 | 2,557 ms |
コンパイル使用メモリ | 198,924 KB |
実行使用メモリ | 7,848 KB |
最終ジャッジ日時 | 2025-04-17 11:05:41 |
合計ジャッジ時間 | 5,574 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 13 WA * 27 |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; const ll MOD = 1000000007; // Z-algorithm on string s, returns Z array of length n (1-based indexing for runs) vector<int> Zalgo(const string &s) { int n = s.size(); vector<int> Z(n); int l = 0, r = 0; Z[0] = n; for(int i = 1; i < n; i++) { if(i <= r) Z[i] = min(r - i + 1, Z[i - l]); while(i + Z[i] < n && s[Z[i]] == s[i + Z[i]]) Z[i]++; if(i + Z[i] - 1 > r) { l = i; r = i + Z[i] - 1; } } return Z; } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector<ll> A(N); for(int i = 0; i < N; i++) cin >> A[i]; string S; cin >> S; // Compute Z on S vector<int> Z = Zalgo(S); // prefix sums of A for runs (1-based for convenience) vector<ll> pref(N+1, 0); for(int i = 1; i <= N; i++) { pref[i] = pref[i-1] + A[i-1]; } ll ans = 0; ll A1 = A[0]; // Precompute half-sum for triangular terms auto tri = [&](ll x){ x %= MOD; return x * ((x + 1) % MOD) % MOD * ((MOD + 1) / 2) % MOD; }; for(int u = 1; u <= N; u++){ int r = Z[u-1]; // number of matching runs if(r <= 0) continue; ll Au = A[u-1]; // sum1: sum over t=1..Au of min(A1, t) ll sum1 = 0; if(Au <= A1){ sum1 = tri(Au); } else { // A1 * (Au - A1) + sum_{t=1..A1} t ll part1 = (A1 % MOD) * ((Au - A1) % MOD) % MOD; ll part2 = tri(A1); sum1 = (part1 + part2) % MOD; } ans = (ans + sum1) % MOD; // if r >= 2, additional if(r >= 2){ // number of t such that full first-run match: t <= Au - A1 + 1 ll C = Au - A1 + 1; if(C <= 0) continue; C %= MOD; // compute extraLen = sum_{i=2..r-1} A[i] + min(A[r], A[u+r-1]) // careful: run index u+r-1 <= N? if(u + r - 2 >= N) { // suffix runs end before completing r runs // actually Z gives char matches but run-level may be truncated // so effective r_run = number of runs fully inside string // But suffix run count is N-u+1; we match at most that many runs r = min(r, N - u + 1); if(r < 2) continue; } ll sumRuns = (pref[r-1] - pref[1] + MOD) % MOD; // sum A[2..r-1] ll minLast = min(A[r-1], A[u+r-2]) % MOD; // A[r], A[u+r-1] ll extra = (sumRuns + minLast) % MOD; ans = (ans + C * extra) % MOD; } } cout << ans << "\n"; return 0; }