除法分块 luogu2261 (坑)

除法分块

除法分块 是指使用分块计算的方法求S=i=1nkiS=\sum^{n}_{i=1}{\lfloor{\frac{k}{i}}\rfloor}的值。
举个例子。当 n=20n=20 时,有

ii 11 22 33 44 55 66 77 88 99 1010 1111 1212
20i\lfloor\frac{20}{i}\rfloor 2020 1010 66 55 44 33 22 22 22 22 11 11

我们可以把 i[1,n]\forall i\in[1,n] 分成若干块,使得每块的 i\forall inn 的值向下取整后相等。
S=20+10+6+5+4+3+2×4+1×10\therefore S=20+10+6+5+4+3+2\times4+1\times10

题目描述 luogu2261\text{luogu2261}

给出正整数 nnkk 计算 G(n,k)=k  mod  1+k  mod  2+k  mod  3++k  mod  nG(n, k)=k\ \bmod\ 1 + k\ \bmod\ 2 + k\ \bmod\ 3 + \cdots + k\ \bmod\ n的值。

输入格式

两个整数 n,kn,k

输出格式

答案。

输入样例

10 5

输出样例

29

说明

对于 30%30\% 的数据,有 n,k1000n , k \leq 1000
对于 60%60\% 的数据,有 n,k106n , k \leq 10^6
对于 100%100\% 的数据,有 n,k109n , k \leq 10^9

Solution 2261\text{Solution 2261}

根据定义,有 kmod  n=kn×knk\mod n=k-n\times\lfloor\frac{k}{n}\rfloor
依题意得G(n,k)=i=1n(kmod  i)=i=1n(ki×ki)=nki=1n(i×ki)\begin{aligned} G(n,k)&=\sum_{i=1}^{n}{(k\mod i)}\\ &=\sum_{i=1}^{n}{(k-i\times\lfloor\frac{k}{i}\rfloor)}\\ &=nk-\sum_{i=1}^{n}{(i\times\lfloor\frac{k}{i}\rfloor)} \end{aligned}

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,k;

int main(){
   scanf("%lld%lld",&n,&k);
   ll ans=n*k,r;
   for(ll l=1;l<=n;l=r+1){
   	if(k/l) r=min(n,k/(k/l));
   	else r=n;
   	ans-=(r-l+1)*(k/l)*(l+r)/2;
   }
   printf("%lld",ans);
}
posted @ 2019-04-08 15:30  TeacherDai  阅读(136)  评论(0)    收藏  举报