2020牛客多多校第七场 D(整除分块)

29 篇文章 0 订阅
26 篇文章 0 订阅

思路:
1 : 从 第一个操作 知道所有 1,k 都是 传奇元组 ,再对(1,1)运用2操作,知道所有(x,1)都是传奇数组。故有 n+k-1个
2: 对1,2 1,3 ,1,4 …进行操作2 一直循环操作下去 发现是 第一位数 是 xk+1,故若第一位 - 1 是第二位的倍数则 是传奇数组。
3 同上,进行操作3,会发现, 第一位是 x
k ,故若第一位是第二位的倍数,则是传奇数组。

故即使求 对于所有的1~k,找到n是k的倍数 的个数和n-1是k倍数的个数。

找倍数的,n/k 就可以知道有多少个。

i = 2 是因为 i =1 的时候特殊处理。

故求 ∑ i = 2 k n / i \sum_{i=2}^k n/i i=2kn/i ∑ i = 2 k ( n − 1 ) / i \sum_{i=2}^k (n-1)/i i=2kn1/i 而这个就是整除分块的模板了。
整除分块观看地址:地址

代码:

#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
 
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 1e9+7;
const int N = 8010;

int ans = 0;
void div_int(int n,int k){
	for(int l=2,r=0;l<=n&&l<=k;l=r+1){
		r = min(k,n/(n/l));
		ans = (ans + (r-l+1)%mod*(n/l)%mod) % mod;
	}
}

signed main(){
	IOS;
	#ifdef ddgo
		freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
	#endif
	
	int n,k; cin>>n>>k;
	ans = (n+k-1)%mod;
	div_int(n,k);div_int(n-1,k);
	cout<<ans<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值