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;
}



你可能感兴趣的:(poj 3067 - Japan(树状数组))