QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#882039#9244. Counting StringschenkWA 0ms8204kbC++142.4kb2025-02-04 20:44:362025-02-04 20:44:37

Judging History

This is the latest submission verdict.

  • [2025-02-04 20:44:37]
  • Judged
  • Verdict: WA
  • Time: 0ms
  • Memory: 8204kb
  • [2025-02-04 20:44:36]
  • Submitted

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'