題意:在Japan的東海岸和西海岸分別有n個城市和m個城市,分別編號爲1..n和1..m。現在要修建k條高速路連接兩岸的城市,告訴你這k座高速路連接的兩邊城市編號,請你計算,這些橋的交點數量。(在城市處的交點不算)
這道題就是求逆序對。將東邊的城市按編號從小到大排序,然後分治尋找西邊城市的編號的逆序對就可以了。注意排序時也要把西邊的城市按升序排列。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,k,times;
struct data
{
long long l,r;
};
data a[500002],t[500002];
bool cmp(data a,data b)
{
if(a.l==b.l) return a.r<b.r;
return a.l<b.l;
}
long long fac(int x,int y)
{
if(x>=y) return 0;
int m=(x+y)>>1;
long long t1=fac(x,m);
long long t2=fac(m+1,y);
long long t3=0;
int i=x,e=x,j=m+1;
while(i<=m&&j<=y)
{
if(a[i].r>a[j].r)
{
if(a[i].l<a[j].l) t3+=m-i+1;
t[e++]=a[j++];
} //t3+=j-m+1
else t[e++]=a[i++];
}
while(i<=m) t[e++]=a[i++];
while(j<=y) t[e++]=a[j++];
for(int i=x;i<=y;i++)
{
a[i]=t[i];
}
return t1+t2+t3;
}
int main()
{
//freopen("1.txt","r",stdin);
scanf("%d",×);
for(int j=1;j<=times;j++)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
}
sort(a+1,a+k+1,cmp);
long long ans=fac(1,k);
printf("Test case %d: %I64d\n",j,ans);
}
return 0;
}