任意相邻2位差的绝对值不大于1的数为阶梯数(和windy数恰好相反),譬如:121,456543 现在给到一个数m,求10到m之间所有阶梯数的和。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<bitset>
#include<set>
#include<stack>
#include<map>
#include<list>
#include<new>
#include<vector>
#define MT(a,b) memset(a,b,sizeof(a));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const double E=2.718281828459;
const ll MOD=1e9+7;
const int INF=0x3f3f3f3f;
struct node
{
ll cnt;
ll sum;
} ans_sum,dp[20][10];
ll prew[25],num[25];
node dfs(ll pos,bool lead,bool limit,int pre)
{
if(pos==0)
return node{1,0};
if(!lead&&!limit&&dp[pos][pre].cnt!=-1)
return dp[pos][pre];
ll up=limit?num[pos]:9;
node ans= {0,0};
for(ll i=0; i<=up; i++)
{
if(!lead&&abs(pre-i)>1)continue;
node next=dfs(pos-1,lead&&i==0,limit&&i==num[pos],i);
ans.cnt+=next.cnt;
ans.cnt%=MOD;
ans.sum+=(next.sum+next.cnt*i%MOD*prew[pos]%MOD)%MOD;
ans.sum%=MOD;
}
if(!lead&&!limit)
dp[pos][pre]=ans;
return ans;
}
ll solve(ll x)
{
ll sign=0;
while(x)
{
num[++sign]=x%10;
x=x/10;
}
memset(dp,-1,sizeof(dp));
ans_sum=dfs(sign,1,1,0);
return ans_sum.sum;
}
void init()
{
prew[1]=1;
for(int i=2; i<=20; i++)
prew[i]=(prew[i-1]*10ll)%MOD;
return ;
}
int main()
{
init();
ll l,r,t;
scanf("%lld",&t);
while(t--)
{
scanf("%lld %lld",&l,&r);
printf("%lld\n",((solve(r)-solve(l-1))%MOD+MOD)%MOD);
}
return 0;
}