正题
luogu题目链接:https://www.luogu.org/problemnew/show/P4193
题目大意
定义一个函数D(x)D(x)D(x)和S(x)S(x)S(x),S(x)S(x)S(x)表示xxx的各位之和
D(n)={D(S(n)),S≥10S(n)D(n)=\left\{\begin{matrix} \\D(S(n)),S\geq 10 \\S(n) \\ \\ \end{matrix}\right.D(n)=⎩⎪⎪⎨⎪⎪⎧D(S(n)),S≥10S(n)
求L∼RL\sim RL∼R之间有多个xxx满足x=D(k)∗kx=D(k)*kx=D(k)∗k
解题思路
因为(n−S(n))mod9=0(n-S(n))\ mod\ 9=0(n−S(n)) mod 9=0,所以D(n)=(n−1)mod9+1D(n)=(n-1)\ mod\ 9+1D(n)=(n−1) mod 9+1
22680modx=0(x∈[1..9])22680\ mod\ x=0(x\in [1..9])22680 mod x=0(x∈[1..9])
若一个数n=D(k)∗kn=D(k)*kn=D(k)∗k,那么n+22680=(k+22680D(k))∗D(k)n+22680=(k+\frac{22680}{D(k)})*D(k)n+22680=(k+D(k)22680)∗D(k)
证明:
(k+22680D(k))∗D(k)−k∗D(k)=22680(k+\frac{22680}{D(k)})*D(k)-k*D(k)=22680(k+D(k)22680)∗D(k)−k∗D(k)=22680
(k+22680D(k)−k)∗D(k)=22680(k+\frac{22680}{D(k)}-k)*D(k)=22680(k+D(k)22680−k)∗D(k)=22680
(k+22680D(k)−k)∗D(k)=22680(k+\frac{22680}{D(k)}-k)*D(k)=22680(k+D(k)22680−k)∗D(k)=22680
k∗D(k)+22680−k∗D(k)=22680k*D(k)+22680-k*D(k)=22680k∗D(k)+22680−k∗D(k)=22680
22680=2268022680=2268022680=22680
证毕
然后之间根据循环节预处理1∼226801\sim 226801∼22680的就好了
codecodecode
#include<cstdio>
#define LCM 22680
#define ll long long
using namespace std;
ll n,f[1000000],ans;
ll D(ll x)
{return (x-1)%9+1;}
ll ask(ll x)//1~x的个数
{return x/LCM*ans+f[x%LCM];}
int main()
{scanf("%lld",&n);for(ll i=1;i<=LCM;i++)//预处理{for(ll j=1;j<=9;j++)if(D(i/j)==j&&i%j==0){f[i]=1;ans++;break;}f[i]+=f[i-1];}while(n--){ll l,r;scanf("%lld%lld",&l,&r);printf("%lld\n",ask(r)-ask(l-1));}
}