题目大意:
求[l,r]中满足"存在长度至少为2的回文子串"的数的个数。
题解:
存在长度至少为2的回文子串意味着我们只需要考虑是否存在'aa'或者'aba'这种形式的子串就行了。
因此我们可以定义状态为dp[pos][pre1][pre2][flag]表示枚举到pos位,pre1表示上一个数位,pre2表示上上一个数位,flag表示前面是否已经存在'aa'或者'aba'这种形式的回文子串。
但是这里我们需要把pre2初始化的值设为-1,这样有前导0时才不会影响到非前导0的首位的下一位。
因为数位最大为1000,我们需要考虑用字符串存储(
其实更方便了),开始的l-1需要提前处理好。代码实现:
#pragma GCC optimize(2) #include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <cstdio> #include <cstdlib> #include <vector> #include <map> #include <set> #include <stack> #include <queue> #define PI atan(1.0) * 4 #define E 2.718281828 #define rp(i, s, t) for (register int i = (s); i <= (t); i++) #define RP(i, t, s) for (register int i = (t); i >= (s); i--) #define ll long long #define ull unsigned long long #define mst(a, b) memset(a, b, sizeof(a)) #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 #define pii pair<int, int> #define mp make_pair #define pb push_back #define debug printf("ac\n"); using namespace std; inline int read() { int a = 0, b = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') b = -1; c = getchar(); } while (c >= '0' && c <= '9') { a = (a << 3) + (a << 1) + c - '0'; c = getchar(); } return a * b; } const ll mod = 1e9+7; int a[1005],num; ll dp[1005][10][10][2]; ll dfs(int pos,int pre1,int pre2,int flag,int lead,int limit){ if(pos==-1) return flag; if(!lead&&!limit&&dp[pos][pre1][pre2][flag]!=-1&&pre2!=-1) return dp[pos][pre1][pre2][flag]; int up=limit?a[pos]:9; ll ans=0; rp(i,0,up) ans=(ans+dfs(pos-1,i,lead?-1:pre1,flag||(!lead&&i==pre1)||(!lead&&i==pre2),lead&&i==0,limit&&i==a[pos]))%mod; if(!limit&&!lead&&pre2!=-1) return dp[pos][pre1][pre2][flag]=ans; return ans; } ll solve(string x){ int len=x.size(); num=0; int i=0; while(i<=len-1) a[num++]=x[len-i-1]-'0',i++; return dfs(num-1,0,-1,0,1,1); } int main(){ string l,r; mst(dp,-1); cin>>l>>r; int len=l.size(); if(l[len-1]-'0'>0) l[len-1]--; else{ int index=len-1; while(l[index]=='0'&&index>0) l[index]='9',index--; l[index]--; string temp=""; rp(i,0,len-1) if(l[i]!='0'){ index=i; break; } rp(i,index,len-1) temp+=l[i]; l=temp; } printf("%lld\n",((solve(r)-solve(l))+mod)%mod); return 0; }