Luogu P2261 [CQOI2007]余数求和
Posted bljfy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P2261 [CQOI2007]余数求和相关的知识,希望对你有一定的参考价值。
题目大意
给定两个数$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 imes lfloor frac{a}{b} floor}$那么之前的式子就可以变成$$large{G(n,k) = prod_{i=1}^{n}k-i imes lfloor frac{k}{i} floor=n imes k-prod_{i=1}^{n}i imes lfloor frac{k}{i} floor}$$。
代码实现
#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); }
以上是关于Luogu P2261 [CQOI2007]余数求和的主要内容,如果未能解决你的问题,请参考以下文章