給定字符串 s (|s|≤5000),定義「半回文」:對所有奇數位置 i,s[i] == s[n-i+1]。求所有半回文子串按字典序第 k 個。
ok[l][r] 表示 s[l..r] 是否半回文
ok[l][r] = (s[l]==s[r]) && ok[l+2][r-2](跳過偶數位)cnt(以此節點結尾的半回文串數)、sum(子樹總數)sumbool ok[5005][5005];
struct TrieNode {
int cnt=0, sum=0;
TrieNode* ch[2]={nullptr,nullptr};
};
void insert(int l, int r, TrieNode* root) {
TrieNode* p = root;
for (int i = l; i <= r; ++i) {
int c = s[i]-'a';
if (!p->ch[c]) p->ch[c] = new TrieNode();
p = p->ch[c];
if (ok[l][i]) { p->cnt++; p->sum++; }
}
}
void dfs(TrieNode* u) {
for (int c=0;c<2;++c) if (u->ch[c]) {
dfs(u->ch[c]);
u->sum += u->ch[c]->sum;
}
}
void kth(TrieNode* u, int& k, string& ans) {
k -= u->cnt;
if (k <= 0) return;
for (int c=0;c<2;++c) if (u->ch[c]) {
if (u->ch[c]->sum >= k) {
ans += 'a'+c;
kth(u->ch[c], k, ans);
return;
} else k -= u->ch[c]->sum;
}
}