题意
求[l,r]中存在回文子串的数的个数。答案对1e9+7取模。
n<=1e1000
题解
这道题想不到正解的思路就很麻烦,看到题解就打开了新世界;
完美的利用了回文串的性质,如果是偶数回文串,那么就肯定有一个长度为2的回文串,那么就有一个数位等于前一位;同理奇数回文串就有一个数位等于前前一位。
因为题目只要出现回文串,没关注长度,所以只要关注这两个就可以了。
其实很想挺简单,可能是自己积累太少了没想到。
不过当时是真的觉得这是我做到的最妙的题。(2019.5.24 00:23:40)
那么状态就很简单了,f[pos][pre][ppre][opy][lim],opt为是否出现回文串。
#include<bits/stdc++.h> using namespace std; const int mod=1000000007; #define ll long long //只要有一个数等于它前一个或前前一个数就是萌数 char l[1005],r[1005]; int len,num[1005]; ll f[1005][11][11][2][2]; ll dfs(int s,int pre,int ppre,bool opt,bool lim){ if(!s) return opt; if(f[s][pre][ppre][opt][lim]!=-1) return f[s][pre][ppre][opt][lim]; int mx=lim?num[s]:9; ll temp=0; for(int i=0;i<=mx;i++){ temp=(temp+dfs(s-1,(pre==10&&i==0)?10:i,pre,opt||i==pre||i==ppre,lim&&i==mx))%mod; } return f[s][pre][ppre][opt][lim]=temp%mod; } ll cx(){ memset(f,-1,sizeof(f)); len=strlen(l+1); for(int i=1;i<=len;i++) num[i]=l[len-i+1]-'0'; num[1]--; for(int i=1;i<=len;i++){ if(num[i]>=0) break; num[i]+=10;num[i+1]--; } if(!num[len]) len--; ll temp1=dfs(len,10,10,false,true); memset(f,-1,sizeof(f)); len=strlen(r+1); for(int i=1;i<=len;i++) num[i]=r[len-i+1]-'0'; ll temp2=dfs(len,10,10,false,true); return temp2-temp1; } int main(){ scanf("%s%s",l+1,r+1); printf("%lld",(cx()%mod+mod)%mod); }