标签:ace div can mod 范围 == pre 开始 想象力
给定两个数$\large n$和$\large k$求$$\large {G(n,k)=\sum_{i=1}^{n}k\ mod\ i}$$。
很明显,60分的暴力很好拿,但是数据范围限制了你的想象力。暴力绝对会被卡死。所以考虑有没有规律可寻。
自己手玩了一下数据发现最后$\large{i>k}$的时候余数都是一样的,都是$\large k$,那么其他的部分是不是也是相同的呢?
于是又开始YY。最后发现整个$\large{k\ mod \ i}$序列可以分为好几个子序列,每个子序列的余数相同。
所以可以用分块来解决,分块的话,考虑每次计算一个余数相同的序列的左右端点,就可以算出这一段的余数之和。
假设我们知道$\large{a\ mod\ b = a - b \times \lfloor \frac{a}{b}\rfloor}$那么之前的式子就可以变成$$\large{G(n,k) = \prod_{i=1}^{n}k-i\times \lfloor \frac{k}{i}\rfloor=n\times k-\prod_{i=1}^{n}i\times \lfloor \frac{k}{i}\rfloor}$$。
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
LL n, k, Ans;
int main() {
scanf("%lld%lld", &n, &k);
for(LL l=1, r; l<=n; l=r+1) {
LL t = (k/l);
if(t == 0) r = n;
else r = min(k/t, n);
Ans -= t*(r-l+1)*(r+l)/2;
}
printf("%lld", Ans+n*k);
}
标签:ace div can mod 范围 == pre 开始 想象力
原文地址:https://www.cnblogs.com/bljfy/p/9411395.html