QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#882039 | #9244. Counting Strings | chenk | WA | 0ms | 8204kb | C++14 | 2.4kb | 2025-02-04 20:44:36 | 2025-02-04 20:44:37 |
Judging History
answer
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
const int N = 1e5 + 5;
int n;
char s[N];
int sa[N], rk[N << 1], oldrk[N << 1], cnt[N], tmp[N], h[N], st[20][N], lg2[N];
int mu[N];
bool vis[N];
inline int query(int l, int r) {
int i = lg2[r - l + 1];
return std::min(st[i][l], st[i][r - (1 << i) + 1]);
}
int main() {
std::ios::sync_with_stdio(false);
std::cin >> n >> (s + 1);
for(int i = 1; i <= n; ++i) rk[i] = s[i];
int m = 300;
for(int w = 1; w <= n; w <<= 1) {
std::memcpy(oldrk, rk, sizeof rk);
for(int i = 0; i <= m; ++i) cnt[i] = 0;
for(int i = 1; i <= n; ++i) ++cnt[rk[i + w]];
for(int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
for(int i = n; i >= 1; --i) tmp[cnt[rk[i + w]]--] = i;
for(int i = 0; i <= m; ++i) cnt[i] = 0;
for(int i = 1; i <= n; ++i) ++cnt[rk[i]];
for(int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1];
for(int i = n; i >= 1; --i) sa[cnt[rk[tmp[i]]]--] = tmp[i];
m = 0;
for(int i = 1; i <= n; ++i) {
auto iseq = [&](int i, int j) {
return oldrk[i] == oldrk[j] && oldrk[i + w] == oldrk[j + w];
};
if(!iseq(sa[i], sa[i - 1])) ++m;
rk[sa[i]] = m;
}
if(m == n) break;
}
int p = 0;
for(int i = 1; i <= n; ++i) {
p -= !!p;
while(i + p <= n && sa[rk[i] - 1] + p <= n && s[i + p] == s[sa[rk[i] - 1] + p]) ++p;
h[rk[i]] = p;
}
lg2[0] = -1;
for(int i = 1; i <= n; ++i) st[0][i] = h[i], lg2[i] = lg2[i >> 1] + 1;
for(int j = 1; j < 20; ++j) for(int i = 1; i + (1 << j) - 1 <= n; ++i) st[j][i] = std::min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
//for(int i = 1; i <= n; ++i) std::cerr << i << " " << sa[i] << " " << &s[sa[i]] << " " << h[i] << "\n";
mu[1] = 1;
for(int i = 2; i <= n; ++i) if(!vis[i]) {
for(int j = 1; i * j <= n; ++j) {
mu[i * j] = (j % i == 0 ? 0 : -mu[j]);
vis[i * j] = 1;
}
}
std::vector<int> pos;
long long ans = 0;
for(int t = 1; t <= n; ++t) if(mu[t]) {
pos.clear();
for(int i = t; i <= n; i += t) pos.push_back(rk[i]);
std::sort(pos.begin(), pos.end());
auto calc = [&](int len) {
int c = 1 + (len - 1) / t;
return 1ll * (1 + 1 + (c - 1) * t) * c / 2;
};
long long sum = calc(n - sa[pos[0]] + 1);
for(int i = 1; i < pos.size(); ++i) sum += calc(n - sa[pos[i]] + 1) - calc(query(pos[i - 1] + 1, pos[i]));
//std::cerr << t << " " << mu[t] << " " << sum << "\n";
ans += mu[t] * sum;
}
std::cout << ans << "\n";
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 8204kb
input:
4 abca
output:
14
result:
ok answer is '14'
Test #2:
score: 0
Accepted
time: 0ms
memory: 6384kb
input:
1 a
output:
1
result:
ok answer is '1'
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 8136kb
input:
2 aa
output:
2
result:
wrong answer expected '3', found '2'