LINK

首先求出 c n t [ i ] cnt[i] cnt[i]表示 P A M PAM PAM节点 i i i代表的回文串出现了几次

那么显然, i i i出现了 c n t [ i ] cnt[i] cnt[i]次,自然 f a i l [ i ] , f a i l [ f a i l [ i ] ] . . . . fail[i],fail[fail[i]].... fail[i],fail[fail[i]]....也至少出现了 c n t [ i ] cnt[i] cnt[i]

所以倒序累加 c n t cnt cnt值,把自己的值加给 f a i l fail fail指针指向的节点就是答案

求出了 c n t cnt cnt值,直接贪心放即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
const int mod = 19930726;
int n; ll k; 
char a[maxn];
int quick(int x,int n)
{
	int ans = 1;
	for( ; n ; n>>=1,x=1ll*x*x%mod )
		if( n&1 )	ans = 1ll*ans*x%mod;
	return ans;
}
struct PAM
{
	int len[maxn],fail[maxn],zi[maxn][26],id,las,cnt[maxn],c[maxn];
	PAM()
	{
		id = las = 1;
		fail[0] = 1,fail[1] = 1,len[0] = 0,len[1] = -1;
	}
	int get_fail(int u,int index)
	{
		while( a[index]!=a[index-len[u]-1] )	u = fail[u];
		return u; 
	}
	void insert(int c,int index)
	{
		int u = get_fail(las,index);
		if( !zi[u][c] )
		{
			int now = ++id, v = get_fail( fail[u],index );
			fail[now] = zi[v][c], len[now] = len[u]+2;
			zi[u][c] = now;
		}
		las = zi[u][c]; cnt[las]++;
	}
	void build()
	{
		int n = strlen( a+1 ); 
		for(int i=1;i<=n;i++)	insert( a[i]-'a',i );	
		int ans = 1;
		for(int i=id;i>=2;i--)	cnt[fail[i]] += cnt[i];
		for(int i=2;i<=id;i++)	c[len[i]] += cnt[i];
		for(int i=n;i>=1;i--)
		{
			if( i%2==0 )	continue;
			if( c[i]>=k )	{ ans = 1ll*ans*quick( i,k)%mod; k=0; break; }
			else	ans = 1ll*ans*quick(i,c[i] )%mod, k-=c[i];
		}
		if( k )	ans = -1;
		cout << ans;
	}
}pam;
signed main()
{
	cin >> n >> k >> ( a+1 );
	pam.build(); 
}