Luogu P3413 SAC#1 – 萌数 题解

Describe

题目链接

定义“萌数”: 存在长度至少为$2$的回文子串。

问$[L,R]$中共有多少个萌数字?

对于$100\%$的数据$0\leq L\leq R \leq {10}^{1000}$。

Solution

数位$dp$裸题。

$$DFS(x,las,lasqr,has,lim,st)$$

分别表示第$x$位,上一个数字是$las$,再上一个数字是$lasqr$,是否到达上限$lim$,是否前导$0$。

萌数一定是形如$11$或$101$式的,所以只要判断$las==i||lasqr==i$即可。

注意$L,R$都需要高精

Code

#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("%lld\n",(ans2-ans1+mod)%mod);//别忘记%%%
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇