社区讨论

不明不白的AC

CF204ELittle Elephant and Strings参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@lxrm4e19
此快照首次捕获于
2024/06/23 21:56
2 年前
此快照最后确认于
2024/06/24 12:31
2 年前
查看原帖
我每次找到符合条件的点是暴力把答案加给每个串的:
CPP
if (mp[st[u].idx].size() >= k) {
	for (auto [i, j]: mp[st[u].idx])
		ans[i] += 1ll * j * (st[u].len - st[st[u].link].len);
}
本来没想过AC只是想验证一下正确性,索性交一发试试,意外获得AC?是数据水还是本来复杂度没问题?
CPP
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

const int N = 2e5 + 5;

int n, k;
string s;
ll ans[N];

namespace SAM {
	struct node {
		int len, link{-1}, trans[26], idx;
	} st[N];

	int tot, cnt, trans[N][26];
	map<int, int> mp[N];
	vector<int> e[N];

	int insert(int c, int last, int idx) {
		int cur = ++tot, p = last;
		st[cur].len = st[p].len + 1;
		st[cur].idx = idx;
		for (; p != -1 && !st[p].trans[c]; p = st[p].link) st[p].trans[c] = cur;
		if (p == -1) {
			st[cur].link = 0;
		} else {
			int q = st[p].trans[c];
			if (st[q].len == st[p].len + 1) {
				st[cur].link = q;
			} else {
				int clone = ++tot;
				st[clone] = st[q];
				st[clone].len = st[p].len + 1;
				st[clone].idx = ++cnt;
				for (; p != -1 && st[p].trans[c] == q; p = st[p].link) st[p].trans[c] = clone;
				st[q].link = st[cur].link = clone;
			}
		}
		return cur;
	}

	void insert(int id) {
		int p = 0;
		for (auto c: s) {
			if (!trans[p][c - 'a']) trans[p][c - 'a'] = ++cnt;
			p = trans[p][c - 'a'];
			mp[p][id]++;
		}
	}

	void bfs() {
		queue<tuple<int, int, int>> q;
		for (int i = 0; i < 26; ++i)
			if (trans[0][i])
				q.emplace(0, i, 0);
		while (!q.empty()) {
			auto [fa, c, come] = q.front();
			q.pop();
			int u = trans[fa][c];
			int last = insert(c, come, u);
			for (int i = 0; i < 26; ++i)
				if (trans[u][i])
					q.emplace(u, i, last);
		}
		for (int i = 1; i <= tot; ++i)
			e[st[i].link].emplace_back(i);
	}

	void merge(map<int, int> &x, map<int, int> &y) {
		if (x.size() > y.size()) swap(x, y);
		for (auto [i, j]: x) y[i] += j;
	}

	void dfs(int u = 0) {
		for (auto v: e[u]) {
			dfs(v);
			merge(mp[st[v].idx], mp[st[u].idx]);
		}
		if (mp[st[u].idx].size() >= k) {
			for (auto [i, j]: mp[st[u].idx])
				ans[i] += 1ll * j * (st[u].len - st[st[u].link].len);
		}
	}
}

int main() {
#ifdef LOCAL
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
	freopen("test.err", "w", stderr);
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

	cin >> n >> k;
	for (int i = 1; i <= n; ++i) {
		cin >> s;
		SAM::insert(i);
	}
	SAM::bfs();
	SAM::dfs();
	for (int i = 1; i <= n; ++i) cout << ans[i] << ' ';

    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...