建回文树,然后判断长度奇偶性,统计下来排序即可。
题目链接:http://www.tsinsen.com/ViewGProblem.page?gpid=A1255
By:大奕哥
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+5; 4 const int M=26; 5 const int mod=19930726; 6 typedef long long ll; 7 ll qmod(ll a,ll b) 8 { 9 ll ans=1; 10 while(b){ 11 if(b&1)ans=ans*a%mod; 12 b>>=1;a=a*a%mod; 13 } 14 return ans; 15 } 16 struct good{ 17 int l,n; 18 bool operator<(const good &b)const{ 19 return l>b.l; 20 } 21 }a[N]; 22 struct Palindromic_Tree{ 23 int nex[N][M]; 24 int fail[N]; 25 int cnt[N]; 26 int num[N]; 27 int len[N]; 28 int S[N]; 29 int last; 30 int n,m; 31 int p; 32 33 int newnode(int l) 34 { 35 for(int i=0;i<M;++i)nex[p][i]=0; 36 cnt[p]=0; 37 num[p]=0; 38 len[p]=l; 39 return p++; 40 } 41 42 void init() 43 { 44 p=0; 45 newnode(0); 46 newnode(-1); 47 last=0; 48 n=0; 49 S[n]=-1; 50 fail[0]=1; 51 } 52 53 int get_fail(int x){ 54 while(S[n-len[x]-1]!=S[n])x=fail[x]; 55 return x; 56 } 57 58 void add(int c){ 59 c-=‘a‘; 60 S[++n]=c; 61 int cur=get_fail(last); 62 if(!nex[cur][c]){ 63 int now=newnode(len[cur]+2); 64 fail[now]=nex[get_fail(fail[cur])][c]; 65 nex[cur][c]=now; 66 num[now]=num[fail[now]]+1; 67 } 68 last=nex[cur][c]; 69 cnt[last]++; 70 } 71 72 void count(){ 73 for(int i=p-1;i>=0;--i)cnt[fail[i]]+=cnt[i]; 74 for(int i=p-1;i>=2;--i) 75 { 76 if(len[i]%2)a[++m].l=len[i],a[m].n=cnt[i]; 77 } 78 } 79 80 void solve(long long k) 81 { 82 sort(a+1,a+1+m); 83 long long ans=1; 84 for(int i=1;i<=m&&k;++i) 85 { 86 if(a[i].n<=k){ 87 ans=ans*qmod(a[i].l,a[i].n)%mod; 88 k-=a[i].n; 89 } 90 else{ 91 ans=ans*qmod(a[i].l,k)%mod;k=0; 92 } 93 } 94 if(k)puts("-1"); 95 else printf("%lld\n",ans); 96 } 97 }T; 98 char s[N]; 99 int l[N]; 100 void solve(int n,long long k) 101 { 102 T.init();int ans=0; 103 for(int i=0;i<n;++i) 104 { 105 T.add(s[i]); 106 } 107 T.count(); 108 T.solve(k); 109 } 110 int main() 111 { 112 int n;long long k; 113 scanf("%d%lld%s",&n,&k,s); 114 solve(n,k); 115 return 0; 116 }