当前位置: 代码迷 >> 综合 >> 2020牛客多校第七场H-Dividing(整除分块)
  详细解决方案

2020牛客多校第七场H-Dividing(整除分块)

热度:10   发布时间:2024-02-06 14:09:44.0

题目
题意:给定N和K,满足二元组(n,k) 1≤n≤N,1≤k≤K.
(1,k)是特殊二元组,如果(n,k)是特殊二元组,①(n + k, k)也是特殊二元组, ②(nk, k) 也是特殊二元组。
问在给定的N和K中有多少个特殊二元组。

由题意,所有特殊二元组都是从(1,k)出发的。如果先进行第二步,则后面所有的二元组是(k,k), (k^2,k) ,(k+k,k)…可见后面的数都是(k的倍数,k)包括了所有k的倍数。如果先进行第一步,这里因为如果再进行第二步会跟第一个思路重合,所以只操作第一步(1+k,k),(1+2k,k)…都是特殊二元组。

答案是 对于每个k,都有floor[N/K]+floor[(N-1)/k]
整除分块
求解在这里插入图片描述

for(int l=1,r;l<=n;l=r+1)
{r=n/(n/l);ans+=(r-l+1)*(n/l);
}
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
const ll mod=1e9+7; 
int main(){ll n,k;scanf("%lld%lld",&n,&k);ll ans=(n+k-1)%mod;for(ll l=2,r;l<=min(k,n-1);l=r+1){r=min((n-1)/((n-1)/l),k);ans=(ans+(r-l+1)*((n-1)/l)%mod)%mod;}for(ll l=2,r;l<=min(k,n);l=r+1){r=min(n/(n/l),k);ans=(ans+(r-l+1)*(n/l)%mod)%mod;}printf("%lld\n",ans);return 0;}

注意l和r在题意中的取值范围