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

题目链接

  • 添加分隔符的目的是给偶数长度的回文串一个中心,本题只要求奇数长度的回文串,那么这一步就可以省略了;而且,字符串加法非常慢
  • 利用回文串的另一半所携带的信息,注意不能超出回文串的范围
  • 在manacher算法的过程中,我们可以顺便得到以字符串中任意一个字符为中心的最长回文串的长度
  • 边修改边询问,才需要用到高级数据结构;如果所有修改都在询问之前,就不需要了
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int ans[2000005],c[1000005],n,cnt[1000005];
long long k;
const int mod=19930726;
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:59  D06  阅读(8)  评论(0编辑  收藏  举报