/* THE PROGRAM IS MADE BY PYY */ /*----------------------------------------------------------------------------// Copyright (c) 2012 panyanyany All rights reserved. URL : http://acm.hdu.edu.cn/showproblem.php?pid=1892 Name : 1892 See you~ Date : Monday, April 16, 2012 Time Stage : one hour Result: 5787399 2012-04-16 21:51:19 Accepted 1892 203MS 8212K 2645 B C++ pyy 5787369 2012-04-16 21:48:37 Wrong Answer 1892 218MS 8212K 2493 B C++ pyy 5787344 2012-04-16 21:46:17 Time Limit Exceeded 1892 3000MS 8184K 2438 B C++ pyy 5787212 2012-04-16 21:34:53 Time Limit Exceeded 1892 3000MS 4184K 2306 B C++ pyy 5787126 2012-04-16 21:28:33 Time Limit Exceeded 1892 3000MS 4184K 2280 B C++ pyy Test Data : Review : 第一次做的时候是984MS,第二次,免去初始化,果断就203MS了…… 刚开始的几次TLE,是因为没有开另一个数组来记录每个格子的状态,直接通过 getsum(x1,y1)-getsum(x1-1,y1-1)来求每个格子的状态,结果就悲剧了…… 二维以上的数组,经常要考虑容斥的问题,我就经常忽略掉,而且下标从1开始也经常 忽略掉,所以悲剧也经常来照顾我…… //----------------------------------------------------------------------------*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <vector> #include <algorithm> #include <iostream> #include <queue> using namespace std ; #define MEM(a, v) memset (a, v, sizeof (a)) // a for address, v for value #define max(x, y) ((x) > (y) ? (x) : (y)) #define min(x, y) ((x) < (y) ? (x) : (y)) #define INF (0x3f3f3f3f) #define MAXN 1010 #define LESN 10002 #define L(x) ((x)<<1) #define R(x) (((x)<<1)|1) #define DB /##/ typedef __int64 LL; int tcase, q; int treeArr[MAXN][MAXN], map[MAXN][MAXN]; inline int lowbit(int x) { return x & (-x); } void add(int x, int y, int val) { int i, j; for (i = x; i < MAXN; i += lowbit(i)) { for (j = y; j < MAXN; j += lowbit(j)) { treeArr[i][j] += val; } } } int getsum(int x, int y) { int i, j; int sum = 0; for (i = x; i > 0; i -= lowbit(i)) { for (j = y; j > 0; j -= lowbit(j)) { sum += treeArr[i][j]; } } return sum; } void swap(int &x, int &y) { int tmp = x; x = y; y = tmp; } int main() { int i, j, k, x1, y1, x2, y2, n1, s; char c; while (scanf("%d", &tcase) != EOF) { for (k = 1; k <= tcase; ++k) { MEM(treeArr, 0); // 不用两个for循环然后add(i,j,1)了 MEM(map, 0); // 不用给map元素全部初始化为1也行 scanf("%d", &q); printf("Case %d:\n", k); while (q--) { getchar(); scanf("%c %d %d", &c, &x1, &y1); ++x1; ++y1; // 题目的坐标是从0开始的,树状数组要求从1开始, switch(c) { case 'S': scanf("%d %d", &x2, &y2); ++x2; ++y2; // 果然,(x2,y2) 可能比 (x1,y1) 要小…… if (x2 < x1) swap(x1, x2); if (y2 < y1) swap(y1, y2); printf("%d\n", (getsum(x2, y2)+getsum(x1-1, y1-1)- getsum(x2, y1-1)-getsum(x1-1, y2))+ (x2-x1+1)*(y2-y1+1)); // 在这里将初始每个格子的值加上 break; case 'A': scanf("%d", &n1); map[x1][y1] += n1; add(x1, y1, n1); break; case 'D': scanf("%d", &n1); s = map[x1][y1]; if (s+1 < n1) n1 = s + 1; add(x1, y1, -n1); map[x1][y1] -= n1; break; case 'M': scanf("%d %d %d", &x2, &y2, &n1); ++x2; ++y2; s = map[x1][y1]; if (s+1 < n1) n1 = s + 1; map[x1][y1] -= n1; map[x2][y2] += n1; add(x1, y1, -n1); add(x2, y2, n1); break; } } } } return 0; }