結果
| 問題 | No.515 典型LCP |
| コンテスト | |
| ユーザー |
kazuma
|
| 提出日時 | 2017-07-26 19:14:58 |
| 言語 | C++17 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 595 ms / 1,000 ms |
| コード長 | 1,694 bytes |
| 記録 | |
| コンパイル時間 | 2,622 ms |
| コンパイル使用メモリ | 210,060 KB |
| 最終ジャッジ日時 | 2025-01-05 01:54:25 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 15 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
class LCP {
static const int id = 1e9;
const int N, n;
vector<string> Ss;
vector<int> data, trans;
int size(int n) {
int res = 1;
while (res < n) res <<= 1;
return res;
}
public:
LCP(const vector<string>& Ss_) :
N(Ss_.size()), n(size(N)), Ss(Ss_), data(n * 2, id), trans(N) {
vector<pair<string, int>> ss(N);
for (int i = 0; i < N; i++) {
ss[i].first = Ss[i];
ss[i].second = i;
}
sort(ss.begin(), ss.end());
for (int i = 0; i < N; i++) {
trans[ss[i].second] = i;
}
vector<int> val(N);
for (int i = 1; i < N; i++) {
const auto& S = ss[i - 1].first;
const auto& T = ss[i].first;
int j = 0, ss = S.size(), ts = T.size();
while (j < ss && j < ts && S[j] == T[j]) {
j++;
}
val[i - 1] = j;
}
for (int i = 0; i < N; i++)
data[i + n] = val[i];
for (int i = n - 1; i >= 0; i--)
data[i] = min(data[i * 2], data[i * 2 + 1]);
}
int Find(int l, int r) {
if (l == r) return Ss[l].size();
l = trans[l], r = trans[r];
if (l > r) swap(l, r);
l += n, r += n;
int res1 = id, res2 = id;
while (l < r) {
if (l & 1) res1 = min(res1, data[l++]);
if (r & 1) res2 = min(data[--r], res2);
l >>= 1; r >>= 1;
}
return min(res1, res2);
}
};
int main()
{
cin.sync_with_stdio(false);
ll N, M;
ll x, d;
cin >> N;
vector<string> s(N);
for (int i = 0; i < N; i++) {
cin >> s[i];
}
LCP lcp(s);
cin >> M >> x >> d;
ll res = 0;
for (int i = 0; i < M; i++) {
ll l = x / (N - 1), r = x % (N - 1);
if (l > r) {
swap(l, r);
}
else {
r++;
}
x = (x + d) % (N * (N - 1));
res += lcp.Find(l, r);
}
cout << res << endl;
return 0;
}
kazuma