版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/85207199
正题
luogu题目链接:https://www.luogu.org/problemnew/show/P4193
题目大意
定义一个函数
D(x)和
S(x),
S(x)表示
x的各位之和
D(n)=⎩⎪⎪⎨⎪⎪⎧D(S(n)),S≥10S(n)
求
L∼R之间有多个
x满足
x=D(k)∗k
解题思路
因为
(n−S(n)) mod 9=0,所以
D(n)=(n−1) mod 9+1
22680 mod x=0(x∈[1..9])
若一个数
n=D(k)∗k,那么
n+22680=(k+D(k)22680)∗D(k)
证明:
(k+D(k)22680)∗D(k)−k∗D(k)=22680
(k+D(k)22680−k)∗D(k)=22680
(k+D(k)22680−k)∗D(k)=22680
k∗D(k)+22680−k∗D(k)=22680
22680=22680
证毕
然后之间根据循环节预处理
1∼22680的就好了
code
#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)
{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));
}
}