分块应用

题目链接

题目描述:

有 t 组测试数据,每组一个 n ,求前 n 个数的倒数和(1 <= n <= 1e8)

思路:打表,没100个数分成一块,对每一块求一次前缀和,对于要求的 n ,判断它最大完全包含的是哪一块,答案就是这一块的前缀和加上后面的数字的倒数和,后面的数字最多99个,循环一次就行了

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
typedef long long ll;
int t, n;
const int block = 1e6 +10;
double a[block];
void csh(){
	a[0] = 0.0;
	double sum = 0;
	for (int i = 1; i <= 1e8 + 10; i++){
		sum += 1.0 / (double)i;
		if(i % 100 == 0)a[i / 100] = sum;
	}
}
int main()
{
	csh();
	scanf("%d", &t);
	int ind = 1;
	while (t--){
		scanf("%d", &n);
		int bb = n / 100;
		double res = a[bb];
		for (int i = (bb) * 100 + 1; i <= n; i++){
			res += 1.0 / (double)i;
		}
		printf("Case %d: ", ind++);
		printf("%.10lf\n", res);
	}
	return 0;
}

蒟蒻有一点不明白,还请大佬指正

我在分块的时候,用一层循环是可以过的,但是我用了两个循环,内层1到100,外层从1到最大块数,TLE了,不懂为什么

posted @ 2019-08-04 13:59  correct  阅读(95)  评论(0)    收藏  举报