QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#586878 | #801. 回文自动机 | xiangji | 0 | 12ms | 230232kb | C++11 | 3.5kb | 2024-09-24 16:19:21 | 2024-09-24 16:19:26 |
Judging History
answer
// #pragma GCC optimize(2)
// #pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "D:/OneDrive/study/cpp/.vscode/debug.h"
#else
#define debug(...) 42;
#endif
#define int long long
#define endl "\n"
#define ull unsigned long long
#define ll __int128_t
mt19937 rd(chrono::system_clock::now().time_since_epoch().count());
const int mod = 998244353;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 10;
const double eps = 1e-6;
const int kind = 26;
struct PAM
{
string s;
int n;
// int kind; // 种类数量
int nxt[MAXN][kind]; // 字符种类数量
int fail[MAXN]; // 当前节点最长回文后缀的节点
int len[MAXN]; // 当前节点表示的回文串的长度
int cnt[MAXN]; // 当前节点回文串的个数, 在getcnt后可得到全部
// int sed[N]; // 以当前节点为后缀的回文串的个数
// int record[N]; // 每个回文串在原串中出现的位置
int ans;
int tot; // 节点个数
int last; // 上一个节点
void init()
{
tot = 0;
ans = 0;
for (int i = 0; i < MAXN; i++)
{
fail[i] = cnt[i] = len[i] = 0;
for (int j = 0; j < kind; j++)
nxt[i][j] = 0;
}
}
int newnode(int lenx)
{
for (int i = 0; i < kind; i++)
nxt[tot][i] = 0;
cnt[tot] = 0;
len[tot] = lenx;
return tot;
}
void build(string ss)
{
tot = 0;
newnode(0);
tot = 1, last = 0;
newnode(-1);
fail[0] = 1;
n = ss.size();
s = " " + ss;
}
int getfail(int x, int n)
{
while (n - len[x] - 1 <= 0 || s[n - len[x] - 1] != s[n])
x = fail[x];
return x;
}
void insert(char cc, int pos, int op)
{
int c = cc - '0';
int p = getfail(last, pos);
if (!nxt[p][c])
{
tot++;
newnode(len[p] + 2);
fail[tot] = nxt[getfail(fail[p], pos)][c];
len[tot] = len[p] + 2;
// sed[tot] = sed[fail[tot]] + 1;
nxt[p][c] = tot;
}
last = nxt[p][c];
cnt[last] += op;
// record[last] = pos;
}
void insert()
{
for (int i = 1; i <= n; i++)
{
if (i <= n / 2)
insert(s[i], i, 0);
else
insert(s[i], i, 1);
}
}
void get_cnt() // 自己需要的答案
{
for (int i = tot; i > 0; i--)
{
cnt[fail[i]] += cnt[i];
if (i >= 2 && len[i] <= n / 2)
{
ans = max(ans, 1ll * cnt[i] * cnt[i] % mod * len[i] % mod) % mod;
}
}
}
int get_diff_cnt() // 本质不同的回文子串个数
{
return tot - 1;
}
int get_all_cnt() // 所有回文子串个数(本质相同的多次计算)
{
int sum = 0;
get_cnt();
for (int i = 2; i <= tot; i++)
sum += cnt[i];
return sum;
}
} pam;
void solve()
{
string s;
cin >> s;
pam.init();
pam.build(s);
pam.insert();
pam.get_cnt();
cout << pam.ans << '\n';
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _ = 1;
// cin>>_;
while (_--)
solve();
return 0;
}
详细
Subtask #1:
score: 0
Wrong Answer
Test #1:
score: 0
Wrong Answer
time: 12ms
memory: 230232kb
input:
bdgedcfadbabbfgeacdgbggaefddebabbfgeacdgbefaecfddffeddacbabfcgecedacbffeddacbabfebadggfafabcdfdeaabdeecgbcecegcgecedacbfgdagbgagafdegecadfebcdbgfacdecdegecadfebbcdfdeaabdbfgcbccfcaebcecfdfccagdafaeaacbggaefddebcbecdafageeaabcbdafadcbecdbcgcbdgedcfadbcaefbdfcbgfcdeceddaaffgcedfcdcgdcgbfdddfdadgagbbef...
output:
7767369
result:
wrong answer expected '5594', found '7767369'
Subtask #2:
score: 0
Skipped
Dependency #1:
0%