manacher算法解题
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了manacher算法解题相关的知识,希望对你有一定的参考价值。
P1659 [国家集训队]拉拉队排练
1.思维误区:长度为5的最大回文串一定也是长度为3的回文串!!
2.快速幂,和取模这样的技巧处理不好,会很容易wa,并且还不知道自己错在哪。
3. ans[p[i]-1]++;
回文串的长度统计.由于区间的对称性,和算法对于回文串的特殊处理,p[i]-1
就是该字符在原串中的回文长度。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=5e6+5;
const int mod=19930726;
string s;
int p[maxn],n,k,ans[maxn],g;
bool cmp(int x,int y)
return x>y;
int fastpow(int x,int y)
int tmp=1;
while(y)
if(y&1)
tmp*=x,tmp%=mod;
x*=x,x%=mod;
y>>=1;
return tmp;
void manacher()
string ss="@#";
for(int i=0;i<s.length();i++)
ss+=s[i],ss+='#';
int len=ss.length();
int mx=0; //当前延伸最远的回文子串,下标的后一位
int id=0; //对称中心
for (int i=1;i<len;i++)
if(i<mx) p[i]=min(p[2*id-i],mx-i);
else
p[i]=1;
while(ss[i+p[i]]==ss[i-p[i]])
p[i]++;
if(p[i]+i>mx)
mx=p[i]+i,id=i;
if((p[i]-1)%2)
ans[p[i]-1]++; //回文串的长度统计
signed main()
cin>>n>>k>>s;
manacher();
int tmp=1,sum=0;
for(int i=n;i>=1;i--)
if(i%2==0) continue;
sum+=ans[i];
if(k>=sum)
tmp*=fastpow(i,sum);
tmp%=mod,k-=sum;
else
tmp*=fastpow(i,k),tmp%=mod;
k-=sum;break;
if(k>0)
cout<<-1<<endl;
cout<<tmp<<endl;
return 0;
P4555 [国家集训队]最长双回文串
https://www.luogu.com.cn/blog/111990/solution-p4555
#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int maxn=5e6+5;
const int mod=19930726;
int p[maxn],l[maxn],r[maxn];
string s1,s2;
void manacher()
s2="@#";
for(int i=0;i<s1.length();i++)
s2+=s1[i],s2+='#';
int mx=0,id=0,len=s2.length();
for(int i=1;i<len;i++)
if(i<mx)
p[i]=min(p[2*id-i],mx-i);
else p[i]=1;
while(s2[i+p[i]]==s2[i-p[i]]) p[i]++;
if(i+p[i]>mx)
mx=i+p[i],id=i;
l[i-p[i]+1]=max(l[i-p[i]+1],p[i]-1);
//以i为开头的最长回文字符串
r[i+p[i]-1]=max(r[i+p[i]-1],p[i]-1);
//以i为结尾的最长回文字符串
for(int i=3;i<=len;i+=2) l[i]=max(l[i],l[i-2]-2);
for(int i=len-2;i>=3;i-=2) r[i]=max(r[i],r[i+2]-2);
int ans=0;
for(int i=3;i<=len;i+=2)
if(l[i]&&r[i])
ans=max(ans,l[i]+r[i]);
cout<<ans<<endl;
signed main()
cin>>s1;
manacher();
return 0;
思维题:map和pair的记录点方式。本题将要标记的点染黑,若是从前往后染色,存在覆盖的问题;从后往前染,则不存在。本题并不求最小次数,用12或21操作。
#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int maxn=5e6+5;
const int mod=19930726;
char ch[105][105];
int n,m;
signed main()
int t;cin>>t;
while(t--)
map<pair<int,int>,pair<int,int> >mp;
mp.clear();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>ch[i][j];
if(ch[1][1]=='1')
cout<<"-1"<<endl;continue;
int ans=0;
for(int i=n;i>=1;i--)
for(int j=m;j>=1;j--)
if(ch[i][j]=='1')
if(i!=1)
mp[i,j]=i-1,j;
else
mp[i,j]=i,j-1;
ans++;
cout<<ans<<endl;
for(int i=n;i>=1;i--)
for(int j=m;j>=1;j--)
if(ch[i][j]=='1')
cout<<mp[i,j].first<<" "<<mp[i,j].second<<" "<<i<<" "<<j<<endl;
return 0;
以上是关于manacher算法解题的主要内容,如果未能解决你的问题,请参考以下文章