正题
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)表示
x
x
x的各位之和
D
(
n
)
=
{
D
(
S
(
n
)
)
,
S
≥
10
S
(
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
∼
R
L\sim R
L∼R之间有多个
x
x
x满足
x
=
D
(
k
)
∗
k
x=D(k)*k
x=D(k)∗k
解题思路
因为
(
n
−
S
(
n
)
)
m
o
d
9
=
0
(n-S(n))\ mod\ 9=0
(n−S(n)) mod 9=0,所以
D
(
n
)
=
(
n
−
1
)
m
o
d
9
+
1
D(n)=(n-1)\ mod\ 9+1
D(n)=(n−1) mod 9+1
22680
m
o
d
x
=
0
(
x
∈
[
1..9
]
)
22680\ mod\ x=0(x\in [1..9])
22680 mod x=0(x∈[1..9])
若一个数
n
=
D
(
k
)
∗
k
n=D(k)*k
n=D(k)∗k,那么
n
+
22680
=
(
k
+
22680
D
(
k
)
)
∗
D
(
k
)
n+22680=(k+\frac{22680}{D(k)})*D(k)
n+22680=(k+D(k)22680)∗D(k)
证明:
( k + 22680 D ( 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 + 22680 D ( k ) − k ) ∗ D ( k ) = 22680 (k+\frac{22680}{D(k)}-k)*D(k)=22680 (k+D(k)22680−k)∗D(k)=22680
( k + 22680 D ( 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 ) = 22680 k*D(k)+22680-k*D(k)=22680 k∗D(k)+22680−k∗D(k)=22680
22680 = 22680 22680=22680 22680=22680
证毕
然后之间根据循环节预处理 1 ∼ 22680 1\sim 22680 1∼22680的就好了
c o d e code 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)//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));
}
}