Luogu P3413 SAC#1 - 萌数 题解
Describe
题目链接
定义“萌数”: 存在长度至少为2的回文子串。
问[L,R]中共有多少个萌数字?
对于100%的数据0leq Lleq R leq {10}^{1000}。
Solution
数位dp裸题。
分别表示第x位,上一个数字是las,再上一个数字是lasqr,是否到达上限lim,是否前导0。
萌数一定是形如11或101式的,所以只要判断las==ilasqr==i即可。
注意L,R都需要高精
Code
代码语言:javascript复制#include<bits/stdc .h>
#define mod 1000000007
#define int long long
using namespace std;
int a[1010],m,f[1010][11][2][2][2],ans1,ans2;
inline int DFS(int x,int las,int lasqr,int has,int lim,int st){//分别表示第$x$位,上一个数字是$las$,再上一个数字是$lasqr$,是否到达上限$lim$,是否前导$0$。
if(x<=0) return has;//结束
if(~f[x][las][has][lim][st]) return f[x][las][has][lim][st];//记忆化
int Max=lim?a[x]:9,res=0;
for(int i=0;i<=Max;i )
res =DFS(x-1,i,st?-1:las,has(!st&&i==las)(!st&&i==lasqr),lim&&(i==Max),st&&(i==0))%mod,res%=mod;//注意前导0
if(!st&&~lasqr) f[x][las][has][lim][st]=res;//记忆化
return res;
}
inline int solve(){
if(m<=1) return 0;
for(int i=1;i<=m/2;i ) swap(a[i],a[m-i 1]);//读入的时候是反的
memset(f,-1,sizeof(f));
return DFS(m,-1,-1,0,1,1);
}
signed main(){
char ch=getchar();while(ch<'0'ch>'9') ch=getchar();
m=0;while(ch>='0'&&ch<='9') a[ m]=ch-'0',ch=getchar();
a[m]--;int j=m;while(a[j]==-1) a[j-1]--,a[j] =10,j--;//L需要-1
ans1=solve();
while(ch<'0'ch>'9') ch=getchar();
m=0;while(ch>='0'&&ch<='9') a[ m]=ch-'0',ch=getchar();
ans2=solve();
printf("%lldn",(ans2-ans1 mod)%mod);//别忘记%%%
}