Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 8376 | Accepted: 2235 |
Description
Input
Output
Sample Input
1 3 4 4 1 4 2 3 3 2 3 1
Sample Output
Test case 1: 5
Source
/* http://acm.pku.edu.cn/JudgeOnline/problem?id=3067 这题一开始使用二维树状数组,case结果正确却TLE. 后来分析了一下发现可以先对输入按照x坐标排序, 然后只需要按照y坐标来处理,这样就从二维树状数 组简化成了一维树状数组,再提交就AC了. 两个方案的代码都有,而且感觉二维树状数组也是对的 注:刚好在城市上的交点不计入最后结果 另外,交点数很大,需要用__int64,一开始用int就WA */ /* 采用二维线短树 #include <iostream> #define MAX_N 1000 using namespace std; __int64 countv[MAX_N + 1][MAX_N + 1]; int numN, numM, numK, caseNum; __int64 total; int lowbit(int p) { return p & (p ^ (p - 1)); } void modify(int row, int col, __int64 val) { int i, j; for(i = row; i <= numN; i += lowbit(i)) for(j = col; j <= numM; j += lowbit(j)) countv[i][j] += val; } __int64 sum(int row, int col) { __int64 res = 0; int i, j; for(i = row; i >= 1; i -= lowbit(i)) for(j = col; j >= 1; j -= lowbit(j)) res += countv[i][j]; return res; } int main() { int i, j, pos1, pos2; scanf("%d", &caseNum); for(i = 1; i <= caseNum; i++) { total = 0; //memset(countv, 0, sizeof(countv)); scanf("%d%d%d", &numN, &numM, &numK); for(pos1 = 1; pos1 <= numN; pos1++) for(pos2 = 1; pos2 <= numM; pos2++) countv[pos1][pos2] = 0; for(j = 1; j <= numK; j++) { scanf("%d%d", &pos1, &pos2); __int64 res1 = sum(pos1 - 1, numM); __int64 res2 = sum(pos1 - 1, pos2); __int64 res3 = sum(numN, pos2 - 1); __int64 res4 = sum(pos1, pos2 - 1); total += res1 - res2 + res3 - res4; modify(pos1, pos2, 1); } printf("Test case %d: %I64d/n", i, total); } return 0; } */ //一维树状数组 #include <iostream> #include <algorithm> #define MAX_N 1000 using namespace std; __int64 countv[MAX_N + 1]; int numN, numM, numK, caseNum; __int64 total; struct input { int rowId, colId; }inputs[MAX_N * MAX_N + 5]; bool compare(const input p1, const input p2) { if(p1.rowId < p2.rowId) return true; else if(p1.rowId == p2.rowId) return p1.colId <= p2.colId; else return false; } int lowbit(int p) { return p & (p ^ (p - 1)); } void modify(int pos, __int64 val) { int i; for(i = pos; i <= numM; i += lowbit(i)) countv[i] += val; } __int64 sum(int pos) { __int64 res = 0; int i; for(i = pos; i >= 1; i -= lowbit(i)) res += countv[i]; return res; } int main() { int i, j, pos1, pos2; scanf("%d", &caseNum); for(i = 1; i <= caseNum; i++) { total = 0; //memset(countv, 0, sizeof(countv)); scanf("%d%d%d", &numN, &numM, &numK); for(pos2 = 1; pos2 <= numM; pos2++) countv[pos2] = 0; for(j = 0; j < numK; j++) { scanf("%d%d", &pos1, &pos2); inputs[j].rowId = pos1; inputs[j].colId = pos2; } sort(inputs, inputs + numK, compare); for(j = 0; j < numK; j++) { pos2 = inputs[j].colId; __int64 res1 = sum(numM); __int64 res2 = sum(pos2); total += res1 - res2; modify(pos2, 1); } printf("Test case %d: %I64d/n", i, total); } return 0; }