KMP+同余最短路die码求调,思路上与第1篇题解相似,从早上起来一直调到现在,谁能帮忙调一下,悬2-3关
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<string>
#include<vector>
#include<list>
#include<queue>
#include<deque>
#include<map>
using namespace std;
#define int long long
#define endl '\n'
#define MAXN 1000005
#define INF 0x3f3f3f3f3f3f3f3f
string s;
int T,n,m,l,cnt,tp,nn,tmp,a[MAXN],nxt[MAXN],bord[MAXN],r[MAXN],pos[MAXN],se[MAXN],st[MAXN],q[MAXN],ans=0;
void Ios()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cout.flags(ios::fixed);
cout.precision(6);
return;
}
void MODE(int len,int b,int d)//同余最短路
{
int cnt1=__gcd(b,d),cnt2=__gcd(b,nn);
for(int i=0;i<n;i++) r[i]=a[i];
for(int i=0;i<b;i++) a[i]=INF;
for(int i=0;i<nn;i++) tmp=r[i]%b,a[tmp]=min(a[tmp],r[i]);
for(int i=0;i<cnt2;i++)
{
tp=0;
q[++tp]=i;
int tmp=(i+nn)%b;
while(tmp!=q[1]) q[++tp]=tmp,tmp=(tmp+nn)%b;
for(int j=tp+1;j<=2*tp;j++) q[j]=q[j-tp];
tp*=2;;
for(int j=2;j<=tp;j++) a[q[j]]=min(a[q[j]],a[q[j-1]]+nn);
}
nn=b;
if(d<0) return;
for(int i=0;i<cnt1;i++)
{
int tp=0;
q[++tp]=i;
int tmp=(i+d)%b;
while(tmp!=q[1]) q[++tp]=tmp,tmp=(tmp+d)%b;
int mp=1;
for(int j=1;j<=tp;j++) if(a[q[j]]<a[q[mp]]) mp=j;
int tmp_cnt1=0;
for(int j=mp;j<=tp;j++) se[++tmp_cnt1]=q[j];
for(int j=1;j<mp;j++) se[++tmp_cnt1]=q[j];
int low=1,high=1;
pos[1]=1;
st[1]=a[se[1]]-d;
for(int j=2;j<=tp;j++)
{
while(low<=high&&pos[low]+len<j) low++;
if(low<=high) a[se[j]]=min(a[se[j]],st[low]+j*d+b);
while(low<=high&&st[high]>=a[se[j]]-j*d)high--;
st[++high]=a[se[j]]-j*(long long)d,pos[high]=j;
}
}
}
signed main()
{
Ios();
cin>>T;
while(T--)
{
cin>>n>>m;
m-=n;
cin>>s;
l=s.size();
nxt[0]=0,nxt[1]=0;
for(int q=1,k=0;q<l;q++)//KMP
{
k=nxt[q];
while(k&&s[k]!=s[q]) k=nxt[k];
if(s[k]==s[q]) k++;
nxt[q+1]=k;
}
int p=nxt[l];
while(p>0)
{
bord[++cnt] =l-p;
p=nxt[p];
}
bord[++cnt]=l;
memset(a,0x3f,sizeof(a));;
nn=n;
for(int i=1,k=1;i<=cnt;)
{
while(bord[k+1]+bord[i]==bord[i+1]+bord[k]) k++;
MODE(k-i-1,bord[i],bord[i+1]-bord[i]);
i=k;
}
for(int i=0;i<nn;i++) if(a[i]<=m) ans=ans+(m-a[i])/nn+1;
cout<<ans<<endl;
ans=cnt=0;
}
return 0;
}
QAQ