CF557E Ann and Half-Palindrome 字典树+dp

现在看这道题也不难啊,不知道考场上为啥没切~

code: 

#include <bits/stdc++.h> 
#define N 5006   
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
struct trie
{
    int size,tag,ch[2];    
}p[N*2500];  
char S[N];    
int f[N][N],tot;           
void dfs(int u) 
{
    p[u].size=p[u].tag;    
    for(int i=0;i<2;++i) 
    {
        if(p[u].ch[i]) 
        {
            int v=p[u].ch[i]; 
            dfs(v);   
            p[u].size+=p[v].size;     
        }   
    }
}
void dfs2(int u,int kth) 
{   
    kth-=p[u].tag;   
    if(kth<=0) 
    {    
        exit(0);    
    }   
    for(int i=0;i<2;++i) 
    {
        if(p[u].ch[i]) 
        { 
            int v=p[u].ch[i]; 
            if(kth>p[v].size) kth-=p[v].size;         
            else {
                printf("%c",i+'a');   
                dfs2(v, kth);      
                break;    
            }
        }
    }
}
int main() 
{ 
    int i,j,n,k,rt=0;    
    // setIO("input"); 
    scanf("%s%d",S+1,&k);  
    n=strlen(S+1);   
    for(i=1;i<=n;++i) f[i][i]=1;    
    for(i=n-1;i>=1;--i) 
    {
        for(j=i+1;j<=n;++j) 
        {    
            if(j-2>=i+2)                
            {   
                if(S[i]==S[j] && f[i+2][j-2]) f[i][j]=1;    
            }
            else
            {
                if(S[i]==S[j]) f[i][j]=1;       
            }
        }
    }       
    for(i=1;i<=n;++i) 
    { 
        rt=0;   
        for(j=i;j<=n;++j) 
        {    
            int c=S[j]-'a';    
            if(!p[rt].ch[c]) 
            {
                p[rt].ch[c]=++tot;   
            }    
            rt=p[rt].ch[c];     
            p[rt].tag+=f[i][j];        
        }
    }    
    dfs(0);     
    dfs2(0,k);    
    return 0; 
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11642403.html