抽象来说就是求逆序对的问题,虽然放在树状数组的章节里,但不一定要用树状数组,归并排序也可以……
还有关于k的范围……起点最多1000个,终点最多1000个,那么连线最多显然是1000*1000个啊……哪里坑了……
#include<cstdio>
#include<algorithm>
#define MAX 1000*1000+3
using namespace std;
struct Road{
int u,v;
}road[MAX],tmp[MAX];
int n,m,k;
long long cnt;
bool cmp(Road a,Road b)
{
if(a.u==b.u) return a.v<b.v;
else return a.u<b.u;
}
void Merge(int l,int m,int r)
{
int i = l;
int j = m + 1;
int k = l;
while(i <= m && j <= r)
{
if(road[i].v > road[j].v)
{
tmp[k++] = road[j++];
cnt += m - i + 1;
}
else
{
tmp[k++] = road[i++];
}
}
while(i <= m) tmp[k++] = road[i++];
while(j <= r) tmp[k++] = road[j++];
for(int i=l;i<=r;i++) road[i] = tmp[i];
}
void Merge_sort(int l,int r)
{
if(l < r)
{
int m = (l + r) >> 1;
Merge_sort(l,m);
Merge_sort(m+1,r);
Merge(l,m,r);
}
}
int main()
{
int t;
scanf("%d",&t);
for(int kase=1;kase<=t;kase++)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++) scanf("%d%d",&road[i].u,&road[i].v);
sort(road+1,road+k+1,cmp);
cnt=0;
Merge_sort(1,k);
printf("Test case %d: %I64d\n",kase,cnt);
}
}
不过既然是在BIT这节里的题,那总归也要用BIT做一下……
#include<cstdio>
#include<algorithm>
#define MAX 1000*1000+3
using namespace std;
struct Road{
int u,v;
}road[MAX];
int n,m,k,c[MAX];
long long cnt;
bool cmp(Road a,Road b)
{
if(a.u==b.u) return a.v<b.v;
else return a.u<b.u;
}
int lowbit(int x){return x&(-x);}
void add(int i,int val)
{
while(i<=m)
{
c[i]+=val;
i+=lowbit(i);
}
}
int sum(int i)
{
int s=0;
while(i>0)
{
s+=c[i];
i-=lowbit(i);
}
return s;
}
int main()
{
int t;
scanf("%d",&t);
for(int kase=1;kase<=t;kase++)
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++) scanf("%d%d",&road[i].u,&road[i].v);
sort(road+1,road+k+1,cmp);
for(int i=1;i<=m;i++) c[i]=0;
cnt=0;
for(int i=1;i<=k;i++)
{
add(road[i].v,1);//road[i].v出现一次,加上
cnt+=sum(m)-sum(road[i].v);//计算出比road[i].v的逆序数,并累加起来
}
printf("Test case %d: %I64d\n",kase,cnt);
}
}
当然啦,事实告诉了我们,用BIT不是没有道理的,各方面都比归并排序求逆序对要好一些。