結果
| 問題 |
No.1848 Long Prefixes
|
| コンテスト | |
| ユーザー |
👑 potato167
|
| 提出日時 | 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;
}
potato167