题目链接 http://poj.org/problem?id=3067
思路:树状数组求逆序数。用结构体记录下每条路链接的两城市s(东海岸)、e(西海岸),按照东海岸编号由小到大对结构体数组排序。排序后西海岸城市编号构成一个序列,求该序列的逆序数。
注意:k最大为1000*1000; ans用__int64; n和m注意区分啊;
#include<cstdio>
#include<algorithm>
using namespace std;
const int num=1005;
int c[num],n,m,k;
struct node
{
int s,e;
}data[1000010];
bool cmp(const node &a,const node &b)
{
if(a.s==b.s)
return a.e<b.e;
return a.s<b.s;
}
int lowbit(int a)
{
return a&(-a);
}
void updata(int a,int add)
{
while(a<=m)
{
c[a]+=add;
a+=lowbit(a);
}
}
int sum(int a)
{
int ans=0;
while(a>0)
{
ans+=c[a];
a-=lowbit(a);
}
return ans;
}
int main()
{
int t,cas,i;
__int64 ans;
//freopen("in.txt","r",stdin);
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=k;i++)
scanf("%d%d",&data[i].s,&data[i].e);
sort(data+1,data+1+k,cmp);
for(i=0;i<=m;i++)
c[i]=0;
ans=0;
for(i=1;i<=k;i++)
{
updata(data[i].e,1);
ans+=(__int64)(i-sum(data[i].e));
}
printf("Test case %d: %I64d\n",cas,ans);
}
return 0;
}