题意:在日本的东西两侧,分别有n,m座城市,这些两个城市之间由一条公路连接。两边的城市都由北向南从1开始编号。
题目将会给出k天路,问这k条路一共有多少个交点。
思路:这题非常灵活,先将这些路按x升序排列,排好以后从最小的x开始遍历,因为x是按序排列,所以能不能有交点,只需要看y的大小即可。按x排序结束以后,就变成了对y数组进行求逆序对了。
代码:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <stack>
#include <queue>
#include <string>
#include <string.h>
#include <math.h>
#include <sstream>
using namespace std;
typedef long long ll;
const int maxn=1e6+9;
struct BIT
{
int n;
ll bit[maxn];
int lowbit(int x){return x&-x;}
void init(int n)
{
this->n=n+1;
memset(bit,0,sizeof(bit));
}
void update(int x,int v)
{
for(int i=x;i<=n;i+=lowbit(i))
{
bit[i]+=v;
}
}
ll query(int x)
{
ll ans=0;
for(int i=x;i>0;i-=lowbit(i))
{
ans+=bit[i];
}
return ans;
}
}bit;
struct Point
{
int x,y;
}p[maxn];
bool cmp(Point a,Point b)
{
if(a.x==b.x)
{
return a.y<b.y;
}
return a.x<b.x;
}
int n,m,k;
ll C[maxn];
int lowbit(int a)
{
return a&(-a);
}
void Modify(int p,int c)
{
for(int i=p;i<=m;i+=lowbit(i))
C[i]+=c;
}
int getsum(int p)
{
ll ans=0;
for(int i=p;i>0;i-=lowbit(i))
{
ans+=C[i];
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T;
cin>>T;
int Case=0;
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<k;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
}
sort(p,p+k,cmp);
//bit.init(k);
memset(C,0,sizeof(C));
ll ans=0;
for(int i=0;i<k;i++)
{
//bit.update(p[i].y,1);
Modify(p[i].y,1);
ans+=getsum(m)-getsum(p[i].y);
}
printf("Test case %d: %lld\n",++Case,ans);
}
return 0;
}