poj 3067 - Japan(树状数组)
先按第一个数从大到小排序,相等的情况下,第二个数按照从大到小排序。。。。。
预处理后,照着树状数组写就行了。。。
注意:k的最大值应取1000*1000
代码如下:
include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <cstdlib> #include <stack> #include <queue> #include <vector> #include <algorithm> #include <set> #include <map> #define M 1005 #define INF 0x7fffffff #define eps 1e-8 #define LL long long #define LLU unsigned long long #define lowbit(x) (x&-x) using namespace std; int c[M], r[M*M], e[M*M], w[M*M], n, m, k, maxx; void add(int x) { for(int i = x; i <= maxx; i+=lowbit(i)) c[i] += 1; } int sum(int x) { int ret = 0; for(int i = x; i > 0; i-=lowbit(i)) ret += c[i]; return ret; } int comp(const int a, const int b) { return e[a]==e[b]?w[a]>w[b]:e[a]>e[b]; } int main () { int kase = 0, t; scanf("%d", &t); while(t--) { LL ans = 0; scanf("%d%d%d", &n, &m, &k); memset(c,0,sizeof(c)); maxx = -INF; for(int i = 1; i <= k; ++i) { scanf("%d%d", &e[i], &w[i]); maxx = max(maxx, w[i]); r[i] = i; } sort(r+1, r+1+k, comp); for(int i = 1; i <= k; ++i) { int d = r[i]; ans += sum(w[d]-1); add(w[d]); } printf("Test case %d: %lld\n", ++kase, ans); } return 0; }