[国家集训队] 拉拉队排练

  • 添加分隔符的目的是给偶数长度的回文串一个中心,本题只要求奇数长度的回文串,那么这一步就可以省略了;而且,字符串加法非常慢
  • 利用回文串的另一半所携带的信息,注意不能超出回文串的范围
  • 边修改边询问,才需要用到高级数据结构;如果所有修改都在询问之前,就不需要了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int ans[2000005],c[1000005],n,cnt[1000005];
long long k;
const int mod=19930726;
long long power(long long n,long long p)
{
	if(p==0)
	{
		return 1;
	}
	else if(p==1)
	{
		return n%mod;
	}
	else if(p%2==0)
	{
		long long tmp=power(n,p/2);
		return tmp*tmp%mod;
	}
	else
	{
		long long tmp=power(n,p/2);
		return tmp*tmp%mod*n%mod;
	}
}
int main()
{
	cin>>n>>k;
	string s;
	cin>>s;
	int id=0,mx=0;
	ans[0]=1;
	for(int i=1;i<s.size();i++)
	{
		int cur;
		if(i<=mx)
		{
			cur=min(ans[2*id-i],mx-i+1);
		}
		else
		{
			cur=1;
		}
		while(i+cur<s.size()&&i-cur>=0&&s[i+cur]==s[i-cur])
		{
			cur++;
		}
		ans[i]=cur;
		if(i+cur-1>mx)
		{
			mx=i+cur-1;
			id=i;
		}
	}
	for(int i=0;i<s.size();i++)
	{
		c[1]++;
		c[ans[i]*2]--;
	}
	for(int i=1;i<=n;i++)
	{
		cnt[i]=cnt[i-1]+c[i];
	}
	if(n%2==0)
	{
		n--;
	}
	long long mul=1;
	for(int i=n;i>=1;i-=2)
	{
		if(k<=cnt[i])
		{
			mul=mul*power(i,k)%mod;
			k=0;
			break;
		}
		else
		{
			k-=cnt[i];
			mul=mul*power(i,cnt[i])%mod;
		}
	}
	if(k==0)
	{
		cout<<mul<<endl;
	}
	else
	{
		puts("-1");
	}
	return 0;
}
posted @ 2024-02-02 22:58  D06  阅读(7)  评论(0编辑  收藏  举报