QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#559207#9244. Counting StringszltWA 2ms28508kbC++144.2kb2024-09-11 20:49:312024-09-11 20:49:32

Judging History

This is the latest submission verdict.

  • [2024-09-11 20:49:32]
  • Judged
  • Verdict: WA
  • Time: 2ms
  • Memory: 28508kb
  • [2024-09-11 20:49:31]
  • Submitted

answer

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;

const int maxn = 200100;
const int logn = 20;

int n, pr[maxn], tot, m, p[maxn], mpr[maxn], st[logn][maxn], dfn[maxn], tim;
int q[maxn], pre[maxn], nxt[maxn], d[maxn];
char s[maxn];
bool vis[maxn];
vector<int> G[maxn], ps[maxn];

struct SAM {
	int lst, tot, fa[maxn], ch[maxn][26], len[maxn];
	
	inline void init() {
		lst = tot = 1;
	}
	
	inline void insert(int k, int c) {
		int u = ++tot, p = lst;
		lst = p;
		len[u] = k;
		for (; p && !ch[p][c]; p = fa[p]) {
			ch[p][c] = u;
		}
		if (!p) {
			fa[u] = 1;
			return;
		}
		int q = ch[p][c];
		if (len[q] == len[p] + 1) {
			fa[u] = q;
			return;
		}
		int nq = ++tot;
		fa[nq] = fa[q];
		len[nq] = len[p] + 1;
		memcpy(ch[nq], ch[q], sizeof(ch[nq]));
		fa[u] = fa[q] = nq;
		for (; p && ch[p][c] == q; p = fa[p]) {
			ch[p][c] = nq;
		}
	}
} sam;

void dfs(int u, int fa) {
	dfn[u] = ++tim;
	st[0][tim] = fa;
	for (int v : G[u]) {
		dfs(v, u);
	}
}

inline int get(int i, int j) {
	return dfn[i] < dfn[j] ? i : j;
}

inline int qlca(int x, int y) {
	if (x == y) {
		return x;
	}
	x = dfn[x];
	y = dfn[y];
	if (x > y) {
		swap(x, y);
	}
	++x;
	int k = __lg(y - x + 1);
	return get(st[k][x], st[k][y - (1 << k) + 1]);
}

struct DS {
	int bel[maxn], blo, L[maxn], R[maxn], a[maxn], b[maxn];
	
	inline void init() {
		blo = sqrt(n);
		for (int i = 1; i <= n; ++i) {
			bel[i] = (i - 1) / blo + 1;
			if (!L[bel[i]]) {
				L[bel[i]] = i;
			}
			R[bel[i]] = i;
		}
	}
	
	inline void update(int x, int y) {
		a[x] += y;
		b[bel[x]] += y;
	}
	
	inline void update(int l, int r, int x) {
		l = max(l, 1);
		if (l > r) {
			return;
		}
		update(l, x);
		update(r + 1, -x);
	}
	
	inline int query(int x) {
		int res = 0;
		for (int i = 1; i < bel[x]; ++i) {
			res += b[i];
		}
		for (int i = L[bel[x]]; i <= x; ++i) {
			res += a[i];
		}
		return res;
	}
} ds;

ll ans = 1;

void work(int x, int t) {
	for (int i : ps[x]) {
		ans += 1LL * (i + 1) * ds.query(i);
	}
	for (int j = t; j <= tot && 1LL * x * pr[j] < n; ++j) {
		vector<int> S;
		for (int k = pr[j]; k <= n; k += pr[j]) {
			if (vis[k]) {
				continue;
			}
			int l = pre[k], r = nxt[k];
			nxt[l] = r;
			pre[r] = l;
			int xx = qlca(p[l], p[k]), yy = qlca(p[k], p[r]);
			if (dfn[xx] < dfn[yy]) {
				swap(xx, yy);
			}
			ds.update(sam.len[xx], sam.len[k] - 1, -1);
			vis[k] = 1;
			d[k] = xx;
			S.pb(k);
		}
		work(x * pr[j], j + 1);
		for (int k : S) {
			int l = pre[k], r = nxt[k];
			nxt[l] = pre[r] = k;
			int xx = d[k];
			ds.update(sam.len[xx], sam.len[k] - 1, 1);
		}
	}
}

void solve() {
	scanf("%d%s", &n, s + 1);
	if (n == 1) {
		puts("1");
		return;
	}
	sam.init();
	p[0] = 1;
	for (int i = 1; i <= n; ++i) {
		sam.insert(i, s[i] - 'a');
		p[i] = sam.tot;
		q[i] = i;
	}
	m = sam.tot;
	for (int i = 2; i <= m; ++i) {
		G[sam.fa[i]].pb(i);
	}
	for (int i = 2; i <= n; ++i) {
		if (!vis[i]) {
			pr[++tot] = i;
			mpr[i] = i;
		}
		for (int j = 1; j <= tot && i * pr[j] <= n; ++j) {
			vis[i * pr[j]] = 1;
			mpr[i * pr[j]] = pr[j];
			if (i % pr[j] == 0) {
				break;
			}
		}
	}
	for (int i = 1; i <= n; ++i) {
		int x = i, y = 1;
		while (x > 1) {
			int t = mpr[x];
			y *= t;
			while (x % t == 0) {
				x /= t;
			}
		}
		ps[y].pb(i);
	}
	dfs(1, 0);
	for (int j = 1; (1 << j) <= m; ++j) {
		for (int i = 1; i + (1 << j) - 1 <= m; ++i) {
			st[j][i] = get(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
		}
	}
	sort(q + 1, q + n + 1, [&](const int &x, const int &y) {
		return dfn[p[x]] < dfn[p[y]];
	});
	for (int i = 1; i <= n; ++i) {
		pre[q[i]] = q[i - 1];
		nxt[q[i]] = q[i + 1];
	}
	ds.init();
	for (int i = 2; i <= m; ++i) {
		ds.update(sam.len[sam.fa[i]], sam.len[i] - 1, 1);
	}
	mems(vis, 0);
	work(1, 1);
	printf("%lld\n", ans);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 26452kb

input:

4
abca

output:

14

result:

ok answer is '14'

Test #2:

score: 0
Accepted
time: 0ms
memory: 16092kb

input:

1
a

output:

1

result:

ok answer is '1'

Test #3:

score: 0
Accepted
time: 2ms
memory: 24468kb

input:

2
aa

output:

3

result:

ok answer is '3'

Test #4:

score: 0
Accepted
time: 0ms
memory: 28448kb

input:

2
ab

output:

3

result:

ok answer is '3'

Test #5:

score: -100
Wrong Answer
time: 0ms
memory: 28508kb

input:

100
xgljgljgljjljjjjljtjljtgljgljgljjljjjjljtjljtjljgljljgljgljjljjjjljtjljtjljgljllljgllgljgljjglljgljl

output:

129085

result:

wrong answer expected '101808', found '129085'