【DDX Round1】T3 收税(tax) 题解
简要题意
T组询问,给定 m, n, x ,求\(\sum_{k = 0} ^ {k < m} {[\frac{k * n + x}{m}]}\)(其中中括号表示向下取整)。
\[𝑇, 𝑚𝑖 ≤ 10^5, 𝑛𝑖, 𝑥𝑖 ≤ 10^9
\]
题解
这个题推一推式子最终的复杂度是O(Tlogn),其中的log用于求gcd(n,m)。
推式子
\[\sum_{k=0}^{m-1} [\frac{k*n+x}{m}]\\
=\sum{\frac{k*n+x - {(k*n+x) \mod m} }{m}}\\
=\sum{\frac{k*n+x}{m}}-\sum{\frac{(k*n+x) \mod m}{m}}\\
=\frac{\frac{m*(m-1)*n}{2}}{m}+\frac{m*x}{m} - \sum{\frac{(k*n+x) \mod m}{m}}
\]
其中:设 \(gcd(n,m)=d,a=m/d,b=n/d,c=x \mod d\)
\[\sum((n*k+x) \mod m )
=\sum(k*n \mod m) + \sum((k*n+x)\mod d)\\
由于k*n\mod d=0,所以上式:\\
=\sum(k*n \mod m) + \sum(x \mod d)
\]
其中:\(k*n\mod m是以a为周期的,并且构成了d个完整周期\)
\[k*n\mod m=k*b*d \mod (a*d) = d*(k*b\mod a)\\由于gcd(a,b)=1,\\所以一个完整周期内部k*b\mod a构成a的完全剩余系,\\即\sum_{一个周期}(k*b\mod a)=\frac{a(a-1)}{2}
\]
所以:
\[\sum((n*k+x)\mod m)=d*d*\frac{a*(a-1)}{2}+m*c=\frac{m*d*(a-1)}{2}+m*c
\]
所以:
\[原式=\sum_{k=0}^{m-1} [\frac{k*n+x}{m}]\\
=\frac{\frac{m*(m-1)*n}{2}}{m}+\frac{m*x}{m} - \sum{\frac{(k*n+x) \mod m}{m}}\\
=\frac{(m-1)*n}{2}+x-\frac{\frac{m*d*(a-1)}{2}+m*c}{m}\\
=\frac{(m-1)*n}{2}+x-\frac{d*(a-1)}{2}-c\\=\frac{m*n-n-m+d}{2}+x-c
\]
至此,我们只需要求得gcd(n,m),便能够O(1)得出答案。
代码
int T, n, m, x, d, c;
int gcd(int a, int b){
return b ? gcd(b, a % b) : a;
}
int main(){
freopen("tax.in", "r", stdin);
freopen("tax.out", "w", stdout);
T = rd();
for(;T--;){
m = rd(), n = rd(), x = rd();
d = gcd(n, m), c = x % d;
printf("%lld\n", (0ll + ((1ll * m * n - n - m + d) >> 1) % Mod + x - c) % Mod);
}
return 0;
}
特别鸣谢:@Wild_Donkey