将East coast当成x,West coast当成y, 这题需要注意的是两条高速公路交点只能在两条高速公路之间,不能在East coast 或 West coast处.
针对以上两种不同的情况排序的规则是不一样的:
<1>计算East coast 和 West coast在内的交点 首先按照 y非增,x非降的顺序进行排序,然后按照排序后的顺序遍历没条高速公路,利用树状数组统计当前高速公路的小于p[i].x的高速公路的条数,最后直接求和即可.
<2>针对情况2,我们采用求补运算的方法 按照 x非降, y非降的顺序进行排序,然后也是利用树状数组进行统计(求补),即可得到交点只在两条高速公路之间的交点的个数.
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <functional>
using namespace std;
//----------------------------------------------------------
#define CL(a,b) memset(a,b,sizeof(a))
#define CLQ(q) while(!q.empty())q.pop();
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define FD(i,a,b) for(int i=a;i>=b;--i)
#define FOS(i,a,b,c) for(int i=a;i<=b;i+=c)
#define FS(i,a) for(int i=0;a[i];++i)
#define REP(i,n) for(int i=0;i<n;++i)
#define PR2(a,n,m) for(int i=0;i<n;++i){for(int j=0;j<m;++j)cout<<a[i][j]<<" ";puts("");}
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define checkMax(a,b) {if(a<b)a=b;}
#define checkMin(a,b) {if(a>b)a=b;}
#define READ(a) freopen(a,"r",stdin)
#define WRITE(a) freopen(a,"w",stdout)
#define sqr(x) ((x)*(x))
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3fLL
#define eps 1e-10
typedef long long LL;
const double pi = acos(-1.0);
const double hpi = asin(1.0);
//-----------------------------------------------------------
/*
const int MAXN = 500010;
struct Node
{
int pos, val;
Node() {}
Node(int t_pos, int t_val) : pos(t_pos), val(t_val) {}
friend bool operator < (const Node &p1, const Node &p2)
{
return p1.val < p2.val;
}
}p[MAXN];
int reflect[MAXN], Tree[MAXN];
LL ans = 0;
int n;
inline int lowbit(int x)
{
return x & (-x);
}
void modify(int x, int value)
{
for(int i = x; i <= n; i += lowbit(i))
{
Tree[i] += value;
}
}
LL getsum(int x)
{
LL ret = 0;
for(int i = x; i > 0; i -= lowbit(i))
{
ret += 1LL*Tree[i];
}
return ret;
}
int main()
{
//READ("aa.in"); WRITE("bb.out");
while(scanf("%d", &n) && n)
{
ans = 0LL;
CL(Tree, 0);
FOR(i, 1, n)
{
scanf("%d", &p[i].val);
p[i].pos = i;
}
sort(p + 1, p + n + 1);
FOR(i, 1, n)
{
reflect[p[i].pos] = i;
}
FOR(i, 1, n)
{
ans += (i - 1 - getsum(reflect[i]));
modify(reflect[i], 1);
}
printf("%lld\n", ans);
//cout << ans << endl;
}
return 0;
}
*/
const int MAXN = 1010;
struct Node
{
int x, y;
Node() {}
Node(int t_x, int t_y) : x(t_x), y(t_y) {}
friend bool operator < (const Node &p1, const Node &p2)
{
if(p1.y == p2.y)
return p1.x <= p2.x;
return p1.y <= p2.y;
}
}p[MAXN*MAXN];
int Tree[MAXN], T, n, N, M, K;
LL ans;
inline int lowbit(int x)
{
return x & (-x);
}
void modify(int x, int value)
{
for(int i = x; i <= n; i += lowbit(i))
{
Tree[i] += value;
}
return ;
}
int getsum(int x)
{
int ret = 0;
for(int i = x; i > 0; i -= lowbit(i))
{
ret += Tree[i];
}
return ret;
}
int main()
{
//READ("aa.in"); WRITE("bb.out");
scanf("%d", &T);
for(int kcase = 1; kcase <= T; ++kcase)
{
scanf("%d %d %d", &N, &M, &K);
for(int i = 1; i <= K; ++i)
{
scanf("%d %d", &p[i].x, &p[i].y);
}
sort(p + 1, p + K + 1);
n = N;
ans = 0; CL(Tree, 0);
for(int i = 1; i <= K; ++i)
{
ans += (i - 1 - getsum(p[i].x));
modify(p[i].x, 1);
}
printf("Test case %d: %lld\n", kcase, ans);
}
return 0;
}