Codeforces 557E Ann and Half-Palindrome (字典树+字符串排序)

来源:互联网 发布:mysql for mac 编辑:程序博客网 时间:2024/05/01 14:38


题意:找出s的子串中字典序第k小的“半回文串”,给出半回文串定义是:对于任意i<=|s|/2 有s[i] = s[len-i+1],其中n<=5000。

思路:枚举字符串长度,然后O(n*n)判定所有字符串是否是半回文串,剩下要做的就是给这些字符串排序,如果直接排序,时间复杂度和空间复杂度都无法承受,考虑用trie树,将原串所有后缀插入到trie树中,如果当前枚举的子串是半回文串那么trie树的权值加一,查找时注意找到答案后要要在答案后面的一位置'\0'。 

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<iostream>#include<algorithm>#include<vector>#include<map>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<ctime>#define eps 1e-6#define LL long long#define pii pair<int, int>//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;const int MAXN = 5100;const int maxnode = 20000000;const int sigma_size = 2;int dp[MAXN][MAXN];int k;int sumv[MAXN][MAXN];char str[MAXN], ans[MAXN];; struct Trie {      int ch[maxnode][sigma_size];      int val[maxnode];      int sz;      Trie() { sz = 1; memset(ch[0], 0, sizeof(ch[0]));};      int idx(char c) {return c - 'a';}        void insert(char *s, int cur) {          int u = 0, n = strlen(s);          for(int i = 0; i < n; i++) {              int c = idx(s[i]);              if(!ch[u][c]) {                  memset(ch[sz], 0, sizeof(ch[sz]));                  val[sz] = dp[cur][cur+i];                  ch[u][c] = sz++;              }              else val[ch[u][c]] += dp[cur][cur+i];              u = ch[u][c];          }      } void dfs(int cur, int pos) {if(k>val[cur]) {k -= val[cur];for(int i = 0; i < 2; i++) {if(!ch[cur][i]) continue;ans[pos] = 'a' + i;dfs(ch[cur][i], pos+1);if(k<=0) return;}}else {k -= val[cur];ans[pos] = 0;}}       } trie;int main() {    //freopen("input.txt", "r", stdin);cin >> (str+1);cin >> k;int len = strlen((str+1));for(int i = 1; i <= len; i++) dp[i][i] = 1;for(int i = 1; i < len; i++) dp[i][i+1] = (str[i]==str[i+1]);for(int i = 3; i <= len; i++) {for(int j = 1; j+i-1 <= len; j++) {dp[j][j+i-1] = ((j+2>j+i-3||dp[j+2][j+i-3]) && str[j]==str[i+j-1]);}}for(int i = 1; i <= len; i++) trie.insert(str+i, i);trie.dfs(0, 0);cout << ans << endl;    return 0;}

 


 



0 0
原创粉丝点击