Codeforces Round #311 (Div. 2) E - Ann and Half-Palindrome(字典树+dp)

题意:

给定一个只有a和b的字符串,输出它第 K 个半回文子串 
半回文串的定义是,所有奇数位置都是回文的 

给出半回文串定义是:对于随意i<=|s|/2 有s[i] = s[len-i+1]
其中字符串长度不超过5000 ,保证有解

思考:
数据量是5000 时间给了1500ms

O(n^2)的算法可行

简单暴力的方法就是n^2 dp 出(i,j)的子串是不是半回文串,再把全部子串插入字典树。在dfs遍历出第k小的串

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5005;
const int mod=1e9+7;
int dp[maxn][maxn];
char s[maxn];
int w;
struct Trie
{
   Trie *child[2];
   int num;
   Trie()
   {
        memset(child,0,sizeof(child));
        num=0;
   }
}trie[maxn*maxn];
int n,k;
int nodeCount=0;
Trie *root,*cur;
Trie *createnode()
{
    return &trie[nodeCount++];
}
void insertnode(int p)
{
    cur=root;
    for(int i=p;i<=n;i++)
    {
        int val=s[i]-'a';
        if(cur->child[val]==NULL) cur->child[val]=createnode();
        cur=cur->child[val];
        cur->num=cur->num+dp[p][i];
    }
}
vector<char>ans;
bool dfs(Trie *cur,int &k)
{
    if(k<=0)
        return 1;
    if(cur->child[0]!=0)
    {
        ans.push_back('a');
        if(cur->child[0]->num!=0)
          k=k-(cur->child[0]->num);
        if(dfs(cur->child[0],k))
                return 1;
        ans.pop_back();
    }
    if(cur->child[1]!=0)
    {
        ans.push_back('b');
        if(cur->child[1]->num!=0)
           k=k-cur->child[1]->num;
        if(dfs(cur->child[1],k))
                return 1;
        ans.pop_back();
    }
    return 0;
}
int main()
{
       scanf("%s%d",s+1,&k);
       n=strlen(s+1);
       for(int i=0;i<=n+3;i++)
        for(int j=0;j<=i;j++)
           dp[i][j]=1;
       for(int len=2;len<=n;len++)
        for(int l=1;l+len-1<=n;l++)
          {
            int r=l+len-1;
            if(s[l]==s[r]&&dp[l+2][r-2]!=0)
                dp[l][r]=1;
            else
                dp[l][r]=0;
          }

    root=createnode();
    for(int i=1;i<=n;i++)
       insertnode(i);
    dfs(root,k);

    for(__typeof((ans).begin())i=ans.begin();i!=ans.end();i++)
       printf("%c",*i);
    printf("\n");
    return 0;
}

题目:

Tomorrow Ann takes the hardest exam of programming where she should get an excellent mark.

On the last theoretical class the teacher introduced the notion of a half-palindrome.

String t is a half-palindrome, if for all the odd positions i () the following condition is held: ti = t|t| - i + 1, where |t| is the length of string t if positions are indexed from 1. For example, strings "abaa", "a", "bb", "abbbaa" are half-palindromes and strings "ab", "bba" and "aaabaa" are not.

Ann knows that on the exam she will get string s, consisting only of letters a and b, and number k. To get an excellent mark she has to find the k-th in the lexicographical order string among all substrings of s that are half-palyndromes. Note that each substring in this order is considered as many times as many times it occurs in s.

The teachers guarantees that the given number kdoesn't exceed the number of substrings of the given string that are half-palindromes.

Can you cope with this problem?

Input

The first line of the input contains string s (1 ≤ |s| ≤ 5000), consisting only of characters 'a' and 'b', where |s| is the length of string s.

The second line contains a positive integer k —  the lexicographical number of the requested string among all the half-palindrome substrings of the given string s. The strings are numbered starting from one.

It is guaranteed that number k doesn't exceed the number of substrings of the given string that are half-palindromes.

Output

Print a substring of the given string that is the k-th in the lexicographical order of all substrings of the given string that are half-palindromes.

Examples

Input

abbabaab
7

Output

abaa

Input

aaaaa
10

Output

aaa

Input

bbaabb
13

Output

bbaabb

Note

By definition, string a = a1a2... an is lexicographically less than string b = b1b2... bm, if either a is a prefix of b and doesn't coincide with b, or there exists such i, that a1 = b1, a2 = b2, ... ai - 1 = bi - 1, ai < bi.

In the first sample half-palindrome substrings are the following strings — a, a, a, a, aa, aba, abaa, abba, abbabaa, b, b, b, b, baab, bab, bb, bbab, bbabaab (the list is given in the lexicographical order).

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值