P7420 题解
TianTian2008 · · 题解
无需多项式,直接转换一下题意然后 dp 即可。
首先可以发现拆分和字符串具体内容无关,只和
第一反应是求元素总和等于
为什么呢?看样例,
具体地,一个长为
然后就很简单了,设
元素总和为
注意会卡内存,滚动数组优化一下。
#include <iostream>
#include <cstdio>
#include <cstring>
#define bas 917
#define mod 899678209
using namespace std;
typedef long long ll;
ll n,m,n1,n2,h1[1000010],h2,f[2][200010],ans;
char str[1000010];
int main() {
scanf("%s",str+1);
n1=strlen(str+1);
for(int i=1;i<=n1;++i) h1[i]=(h1[i-1]*bas+str[i]-'a'+1)%mod;
scanf("%s",str+1);
n2=strlen(str+1);
ll pw=1;
for(int i=1;i<=n2;++i) {
h2=(h2*bas+str[i]-'a'+1)%mod;
pw=pw*bas%mod;
}
for(int i=n2;i<=n1;++i)
if(((h1[i]-h1[i-n2]*pw)%mod+mod)%mod==h2) {
++n;
i+=n2-1;
}
ll l=1,r=n,mid;
while(l<=r) {
mid=l+r>>1;
if((mid*(mid+1)>>1)<=n) {
m=mid;
l=mid+1;
}
else r=mid-1;
}
if((m*(m+1)>>1)<n) ++m;
f[0][0]=1;
for(int i=1;i<=m;++i) {
ll x=i&1,y=x^1;
for(int j=0;j<=n;++j)
if(i>j) f[x][j]=0;
else {
f[x][j]=f[y][j-i]+f[x][j-i];
if(f[x][j]>=mod) f[x][j]-=mod;
}
if(i==1) continue;
for(int j=n-i+1;j<=n;++j) {
ans+=f[x][j];
if(ans>=mod) ans-=mod;
}
}
printf("%lld",ans);
return 0;
}