社区讨论
不明不白的AC
CF204ELittle Elephant and Strings参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @lxrm4e19
- 此快照首次捕获于
- 2024/06/23 21:56 2 年前
- 此快照最后确认于
- 2024/06/24 12:31 2 年前
我每次找到符合条件的点是暴力把答案加给每个串的:
CPPif (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 条回复,欢迎继续交流。
正在加载回复...