整除分块——牛客青铜白银局

整除分块.

找规律太难了
最简单当然暴力求解,但数据是1e13, 必T;
所以另寻他法:有许多n/i的值是一样的,而且它们呈一个块状分布

以10为例,先打个表

i 1 2 3 4 5 6 7 8 9 10
n/i 10 5 3 2 2 1 1 1 1 1
n/(n/i) 1 2 3 5 5 10 10 10 10 10

我们可以发现n/(n/i)相同的一段n/i也相同,且n/(n/i)的值是n/i相同的一块的最后一个i的下标,所以i=7~10这一段其实不用暴力求一变n/i,只需要(n/i)*(n/(n/i)-i+1)即可,然后更新i的值,i=n/(n/i)+1。

看代码

#include<bits/stdc++.h>
#define ll long long
#define T int t;scanf("%d", &t);while(t--)
using namespace std;
int main(){
	int n;
	int mod = 998244353;
	while(cin>>n){		
		int ans = 0;
		for(int i = 1; i <= n; ){
			ans+=((n/i)%mod)*((n/(n/i)-i+1))%mod;
			ans%=mod;
			i=n/(n/i)+1;
		}
		cout<<ans<<endl;
	}

	return 0;
} 

猜你喜欢

转载自blog.csdn.net/HHeyanjie/article/details/107440544