QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#691639 | #9244. Counting Strings | real_sigma_team | WA | 1ms | 3816kb | C++23 | 4.6kb | 2024-10-31 12:22:55 | 2024-10-31 12:22:55 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define all(x) x.begin(), x.end()
// строка -- это последовательность чисел от 1 до размера алфавита
vector<int> suffix_array (vector<int> s) {
if (s.size() == 1) {
return vector<int>(1, 0);
}
s.push_back(0); // добавляем нулевой символ в конец строки
int n = (int) s.size(),
cnt = 0, // вспомогательная переменная: счётчик для сортировки
cls = 0; // количество классов эквивалентности
vector<int> c(n), p(n);
map< int, vector<int> > t;
for (int i = 0; i < n; i++)
t[s[i]].push_back(i);
// «нулевой» этап
for (auto &x : t) {
for (int u : x.second)
c[u] = cls, p[cnt++] = u;
cls++;
}
// пока все суффиксы не стали уникальными
for (int l = 1; cls < n; l++) {
vector< vector<int> > a(cls); // массив для сортировки подсчётом
vector<int> _c(n); // новые классы эквивалентности
int d = (1<<l)/2;
int _cls = cnt = 0; // новое количество классов
for (int i = 0; i < n; i++) {
int k = (p[i]-d+n)%n;
a[c[k]].push_back(k);
}
for (int i = 0; i < cls; i++) {
for (size_t j = 0; j < a[i].size(); j++) {
// если суффикс начинает новый класс эквивалентности
if (j == 0 || c[(a[i][j]+d)%n] != c[(a[i][j-1]+d)%n])
_cls++;
_c[a[i][j]] = _cls-1;
p[cnt++] = a[i][j];
}
}
c = _c;
cls = _cls;
}
return vector<int>(p.begin()+1, p.end());
}
vector<int> calc_lcp(vector<int> val, vector<int> c, vector<int> p) {
int n = val.size();
int current_lcp = 0;
vector<int> lcp(n);
for (int i = 0; i < n; i++) {
if (c[i] == n - 1)
continue;
int nxt = p[c[i] + 1];
while (max(i, nxt) + current_lcp < n && val[i + current_lcp] == val[nxt + current_lcp])
current_lcp++;
lcp[c[i]] = current_lcp;
current_lcp = max(0, current_lcp - 1);
}
return lcp;
}
struct mst {
vector<vector<int>> st;
size_t sz;
mst(const vector<int>& a) {
sz = 1;
while (sz < a.size()) {
sz <<= 1;
}
st.resize(2 * sz);
for (int i = 0; i < a.size(); i++) {
st[sz + i].push_back(a[i]);
}
for (int i = sz - 1; i > 0; i--) {
st[i].resize(st[2 * i].size() + st[2 * i + 1].size());
merge(all(st[2 * i]), all(st[2 * i + 1]), st[i].begin());
}
}
int get(int v, int l, int r) {
l += sz;
r += sz;
int res = 0;
while (l <= r) {
if (l & 1) {
res += upper_bound(all(st[l]), v) - st[l].begin();
l++;
}
if (~r & 1) {
res += upper_bound(all(st[r]), v) - st[r].begin();
r--;
}
l >>= 1;
r >>= 1;
}
return res;
}
};
int32_t main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
string s;
cin >> s;
vector<int> a(n);
for (int i = 0; i < n; i++) {
a[i] = s[i];
}
vector<int> sa = suffix_array(a), osa(n);
for (int i = 0; i < n; i++) {
osa[sa[i]] = i;
}
long long ans = 0;
vector<int> lcp = calc_lcp(a, osa, sa), lcpi(n);
for (int i = n - 1; i > 0; i--) {
lcp[i] = lcp[i - 1];
}
lcp[0] = 0;
for (int i = 0; i < n; i++) {
lcpi[sa[i]] = lcp[i];
}
mst st(lcp), st2(lcpi);
for (int l = 0; l < n; l++) {
if (l == 0) {
ans++;
continue;
}
if (l == 1) {
ans += 2 * st.get(l, 0, n - 1);
ans -= 2 * st2.get(l, n - l, n - 1);
continue;
}
vector<int> bad(2);
bad[0] = -1;
bad[1] = n;
for (int i = l - 1; i + l < n; i += l) {
bad.push_back(osa[i]);
}
sort(all(bad));
for (int i = 1; i < bad.size(); i++) {
ans += 1ll * (l + 1) * st.get(l, bad[i - 1] + 1, bad[i] - 1);
if (bad[i - 1] >= 0 && bad[i - 1] + 1 != bad[i] && lcp[bad[i - 1] + 1] > l && lcp[bad[i - 1]] <= l && sa[bad[i - 1] + 1] + l < n) {
ans += l + 1;
}
}
ans -= 1ll * (l + 1) * st2.get(l, n - l, n - 1);
}
cout << ans << '\n';
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3620kb
input:
4 abca
output:
14
result:
ok answer is '14'
Test #2:
score: 0
Accepted
time: 0ms
memory: 3816kb
input:
1 a
output:
1
result:
ok answer is '1'
Test #3:
score: 0
Accepted
time: 0ms
memory: 3616kb
input:
2 aa
output:
3
result:
ok answer is '3'
Test #4:
score: 0
Accepted
time: 0ms
memory: 3560kb
input:
2 ab
output:
3
result:
ok answer is '3'
Test #5:
score: -100
Wrong Answer
time: 1ms
memory: 3540kb
input:
100 xgljgljgljjljjjjljtjljtgljgljgljjljjjjljtjljtjljgljljgljgljjljjjjljtjljtjljgljllljgllgljgljjglljgljl
output:
162782
result:
wrong answer expected '101808', found '162782'