定义函数 f ( n ) f(n) f(n) 表示对 n n n 一直求数位和直至 n n n 为个位数,即:
f ( n ) = { n n < 10 , f ( g ( n ) ) otherwise, f(n)=\begin{cases} n&n<10, \\ f(g(n))&\text{otherwise,} \end{cases} f(n)={ nf(g(n))n<10,otherwise,
其中 g ( n ) g(n) g(n) 表示 n n n 的数位和。
现在有一个很大的 n n n,你要求 f ( n ) f(n) f(n)。
这个 n n n 是根据四个参数 a , b , m , k a,b,m,k a,b,m,k 生成的,首先生成 k k k 个数 a , a + b , a + 2 b , ⋯ , a + ( k − 1 ) b a,a+b,a+2b,\cdots,a+(k-1)b a,a+b,a+2b,⋯,a+(k−1)b(都在 m o d m \bmod~m mod m 意义下),然后把它们从后往前拼起来,就是 n n n。比如, a = 42 , b = 42 , m = 2018 , k = 18 a=42,b=42,m=2018,k=18 a=42,b=42,m=2018,k=18,会生成 n = 7567146726305885465044624203783362942522101681268442 n=7567146726305885465044624203783362942522101681268442 n=7567146726305885465044624203783362942522101681268442。
0 ≤ a , b ≤ 1 0 9 , 2 ≤ m ≤ 1 0 9 + 7 , 1 ≤ k ≤ 1 0 9 0 \leq a,b \leq 10^9,~~2 \leq m \leq 10^9+7,~~1 \leq k \leq 10^9 0≤a,b≤109, 2≤m≤109+7, 1≤k≤109
多测, T ≤ 1 0 4 T \leq 10^4 T≤104
\\
\\
\\
数论技巧什么的。。还是要时常复习啊。。
首先这个 f f f 是有通项公式的,当 n > 0 n>0 n>0 时 f ( n ) = ( n − 1 ) m o d 9 + 1 f(n)=(n-1) \bmod 9+1 f(n)=(n−1)mod9+1,也即 f(n)=(n%9==0) ?9 :n%9
。
所以我们就是要求 n m o d 9 n \bmod 9 nmod9 的值。(特判 n = 0 n=0 n=0)
注意到 ∀ x > 0 , 1 0 x m o d 9 = 1 \forall x>0,10^x \bmod 9=1 ∀x>0,10xmod9=1,因此对于 n n n 来说,多个数拼起来 m o d 9 \bmod 9 mod9 等价于拆开来 m o d 9 \bmod 9 mod9 再求和,即 n m o d 9 = ∑ i = 0 k − 1 ( ( a + b i ) m o d m ) m o d 9 n \bmod 9 =\sum_{i=0}^{k-1}\big((a+bi) \bmod m \big) \bmod 9 nmod9=∑i=0k−1((a+bi)modm)mod9。
注意到这个式子,是先让 a + b i a+bi a+bi 模 m m m,再求和,模 9 9 9。这样子直接做就不好做,所以要把里面的 m o d m \bmod~m mod m 变形:
n m o d 9 = ∑ i = 0 k − 1 ( ( a + b i ) − ⌊ a + b i m ⌋ ⋅ m ) m o d 9 n \bmod 9 =\sum_{i=0}^{k-1}\big((a+bi)-\lfloor \frac{a+bi}{m} \rfloor \cdot m) \bmod 9 nmod9=i=0∑k−1((a+bi)−⌊ma+bi⌋⋅m)mod9
这样就变成类欧了。
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
LL a,b,m,k;
LL f(LL a,LL b,LL c,LL n)
{
if (!a) return (n+1)*(b/c)%9;
if (a>=c || b>=c)
{
LL sqr=(n&1) ?(n+1)/2*n :n/2*(n+1) ;
sqr%=9;
return (f(a%c,b%c,c,n)+(a/c)*sqr+(n+1)*(b/c))%9;
} else
{
LL m=(a*n+b)/c;
return (m%9*n%9-f(c,c-b-1,a,m-1)+9)%9;
}
}
int T;
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%lld %lld %lld %lld",&a,&b,&m,&k);
a%=m, b%=m;
if (a==0 && (k==1 || k>1 && b==0)) {
puts("0"); continue;}
int ans=((a*k%9+k*(k-1)/2%9*b%9)%9-m*f(b,a,m,k-1)%9+9)%9;
printf("%d\n",(ans==0) ?9 :ans);
}
}