P3396 哈希冲突 TJ

题目链接

思路

暴力 (O(n^2).) 期望得分: (9.)
考虑到此题有两种做法:
(1.) (O(n^2)) 复杂度,每次询问的时候累加:

ans = 0;
for (int q = y;q <= n;q += x) {
	ans += a[q];
}
printf ("%d
",ans);

(2.) (O(n^2)) 的时间预处理,设 (f[i][j]) 表示模 (i) 等于 (j) 的数字总和。

for (int q = 1;q <= n;++ q) {
	for (int w = 1;w <= n;++ w) {
		f[w][q % w] += a[q];
	}
}

于是便有了一种新的思想,根号分治。
顾名思义,根号分治就是前 (sqrt{n}) 的数据预处理,剩下的暴力求解。
预处理复杂度为 (O(nsqrt{n})) ,那么剩下的询问 (p) 就超过了 (sqrt{n}) ,此时只有不到 (sqrt{n}) 个数对他有贡献,每一次暴力的复杂度 (O(sqrt{n}))
剩下还有更改,需要 (O(sqrt{n})) 的时间处理 (f) 数组。
总的时间复杂度是 (O((m + n)sqrt{n}).)

代码

暴力:(小学生都会写的)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1e5 + 50010;
int n, m ,a[MAXN] ,ans;
int main () {
	scanf ("%d%d",&n ,&m);
	for (int q = 1;q <= n;++ q)
		scanf ("%d",&a[q]);
	int x ,y;
	while (m --) {
		ans = 0;
		char ch = getchar ();
		while (ch != 'A' && ch != 'C') ch = getchar ();
		scanf ("%d%d",&x ,&y);
		if (ch == 'A') {
			for (int q = 1;q <= n;++ q) {
				if (q % x == y) ans += a[q];
			}
			printf ("%d
",ans);
		}
		else a[x] = y;
	}
	return 0;
}

正解:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN = 1e5 + 50010;
int n ,m ,a[MAXN];
int f[401][401];//f[i][j]表示模 i 余 j 的池的数的总和 
int main () {
	scanf ("%d%d",&n ,&m);
	for (int q = 1;q <= n;++ q)
		scanf ("%d",&a[q]);
	int siz = sqrt (n);
	for (int q = 1;q <= n;++ q) {
		for (int w = 1;w <= siz;++ w) {
			f[w][q % w] += a[q];
		}
	}
//	for (int q = 1;q <= siz;++ q) {
//		for (int w = 1;w <= siz;++ w) {
//			printf ("mod %d = %d sum: %d
",q ,w ,f[q][w]);
//		}
//	}
	int x ,y ,ans;
	char ch;
	while (m --) {
		ch = getchar ();
		while (ch != 'A' && ch != 'C') ch = getchar ();
		scanf ("%d%d",&x ,&y);
		if (ch == 'A') {
			if (x <= siz) {
				printf ("%d
",f[x][y]);
			}
			else {
				ans = 0;
				for (int q = y;q <= n;q += x) {
					ans += a[q];
				}
				printf ("%d
",ans);
			}
		}
		else {
			int add_ = y - a[x];
			for (int w = 1;w <= siz;++ w) {
				f[w][x % w] += add_;
			}
			a[x] = y;
		}
	}
	return 0;
}

cb
原文地址:https://www.cnblogs.com/tuscjaf/p/13910542.html