[分块处理] Color
来源:互联网 发布:如何获得淘宝内部优惠 编辑:程序博客网 时间:2024/06/05 09:14
Task Color【题目描述】 给定一个长度为N的颜色序列C,对于该序列中的任意一个元素Ci,都有1<=Ci<=M。对于一种颜色ColorK来说,区间[L,R]内的权值定义为这种颜色在该区间中出现的次数的平方,即区间[L,R]内中满足Ci=ColorK的元素个数的平方。接下来给出Q个询问,询问区间[L,R]内颜色[a,b]的权值总和。【输入数据】第1行三个整数N,M,Q。分别代表序列长度,颜色总数和询问总数。第2行N个整数,代表序列Ci。第3行到第Q+2行,每行4个整数l,r,a,b。记上一次计算出的答案为Lans。那么实际的l,r,a,b为给出的l,r,a,b分别xor上Lans。第一个询问的时候Lans=0。【输出数据】总共Q行,对于每一个询问,输出权值总和。【样例输入】4 2 31 1 2 2 1 4 1 210 11 9 103 0 0 0【样例输出】820【数据范围】40% :1<=N,Q<=10000100%:1<=N,Q<=50000
一开始看到数据范围线段树是会挂的,有想到过分块处理,但是实在想不出平方和怎么一起计算出来,所以写了个暴力树状数组(其实根本不用)交了。
之后 Orz cwx,得知可以分段预处理每一段颜色的平方前缀和,对于块之外的杂碎,O(段长) 扫一遍即可, 每遇到一个答案加上原计数器 * 2 + 1,++ 原计数器即可。
然后就开始写了。。。。。写完还是觉得实在不喜欢分段,觉得无论是时间还是空间还是操作都太奇怪了。
#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#define swap(a, b, t) ({t _ = a; a = b; b = _;})#define max(a, b) ({int _ = (a), __ = (b); _ > __ ? _ : __;})#define min(a, b) ({int _ = (a), __ = (b); _ < __ ? _ : __;})#define maxs 26#define maxl 2000#define maxn 50005#define getbl(a) (((a) - 1) / maxl + 1)int n, m, t, Q, ans;int a[maxn], f[maxn], g[maxn], sta[maxn];int b[maxs][maxn];int c[maxs][maxs][maxn], d[maxs][maxs][maxn];void work(){ for (int l, r, x, y; Q --; ) { scanf("%d%d%d%d", & l, & r, & x, & y); l ^= ans, r ^= ans, x ^= ans, y ^= ans; int ll = (l - 2) / maxl + 2, rr = r / maxl; if (ll <= rr) { ans = c[ll][rr][y] - c[ll][rr][x - 1]; for (int i = l, j = (ll - 1) * maxl; i <= j; ++ i) if (x <= a[i] && a[i] <= y) { if (g[a[i]] != Q + 1) f[a[i]] = d[ll][rr][a[i]], g[a[i]] = Q + 1; ans += f[a[i]] ++ * 2 + 1; } for (int i = r, j = rr * maxl + 1; i >= j; -- i) if (x <= a[i] && a[i] <= y) { if (g[a[i]] != Q + 1) f[a[i]] = d[ll][rr][a[i]], g[a[i]] = Q + 1; ans += f[a[i]] ++ * 2 + 1; } } else { ans = t = 0; for (int i = l; i <= r; ++ i) if (x <= a[i] && a[i] <= y) if (g[a[i]] == Q + 1) ++ f[a[i]]; else g[a[i]] = Q + 1, f[a[i]] = 1, sta[++ t] = a[i]; for (int i = 1; i <= t; ++ i) ans += f[sta[i]] * f[sta[i]]; } printf("%d\n", ans); }}void init(){ scanf("%d%d%d", & n, & m, & Q), t = getbl(n); for (int i = 1; i <= n; ++ i) scanf("%d", & a[i]), ++ b[getbl(i)][a[i]]; for (int i = 1; i <= t; ++ i) for (int j = 1; j <= m; ++ j) b[i][j] += b[i - 1][j]; for (int i = 1; i <= t; ++ i) for (int j = i; j <= t; ++ j) for (int k = 1; k <= m; ++ k) { c[i][j][k] = d[i][j][k] = b[j][k] - b[i - 1][k]; c[i][j][k] *= c[i][j][k - 0]; c[i][j][k] += c[i][j][k - 1]; }}int main(){ freopen("color.in", "r", stdin); freopen("color.out", "w", stdout); init(); work(); return 0;}
- [分块处理] Color
- Hdu1556 Color the ball [分块][树状数组]
- 1556 Color the ball(分块)
- HDU 1556 Color the ball 分块
- opencv 图像分块处理
- matlab图片分块处理
- gdal图像分块处理
- GDAL分块处理流程
- 分块处理方法耗时对比
- python-opencv 图像分块处理
- 实现TextView内容分块处理
- 分块。。
- 分块
- 分块
- 分块
- 分块
- 分块
- 分块
- 【mysql】mysql数据库Sql语句执行效率检查–Explain命令
- Mysql,如何建立一个数据库
- 关于对truncate的理解
- htmlparser
- BuddyPress
- [分块处理] Color
- s2Member使用
- asterisk的编解码转换
- php4和php5的区别
- 小谈java连接MySQL
- strcpy和memcpy的区别
- 使用JDBC插入大量数据的性能测试
- jQuery数组处理详解(含实例演示)
- Python语法解析器PLY——lex and yacc in Python