树状数组 之 poj 3067
这道题和 poj 2481 极其相似。。。但wa了几次。。。
原因:
1)对于结果和存储树状数组求和的变量,采用 long long 来保存;
2)从东海岸 number x,到西海岸 number y, 可能建了两条高速
(即从位置 x 到位置 y 可能有两条高速)
故在树状数组求 mySum 时,所传参数为 y-1 (详见代码)
解题思路:
设东海岸位置 x ,西海岸位置 y ,使x 升序,若 x 相等,按 y 升序(可模拟所给范例,有助理解)
#include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; typedef long long int64; int64 bit[1005]; int N, M, K; struct node {int x, y;}; node Arr[1005*1005]; bool Cmp (const node n1, const node n2) { if (n1.x == n2.x) { return n1.y > n2.y;} else return n1.x > n2.x; } int64 mySum(int x) { int64 sum = 0; while (x) { sum += bit[x]; x -= (x&(-x)); } return sum; } void myAdd(int x) { while (x <= 1005) { bit[x] += 1; x += (x&(-x)); } } int64 Solve() { int64 ans = 0; for (int i = 0; i < K; i++) { ans += mySum(Arr[i].y - 1); // wa 原因2 myAdd(Arr[i].y); } return ans; } int main() { //freopen("input.txt", "r", stdin); int T; scanf("%d", &T); for (int cas = 1; cas <= T; cas++) { memset(Arr, 0, sizeof(Arr)); memset(bit, 0, sizeof(bit)); scanf("%d %d %d", &N, &M, &K); for (int i = 0; i < K; i++) { scanf("%d %d", &Arr[i].x, &Arr[i].y); } sort(Arr, Arr + K, Cmp); printf("Test case %d: %lld\n", cas, Solve()); } return 0; }