题目:求逆序数判断交点
题意:
有东西两个海岸,东有n个点,西有m个点,东海岸的第xi个点连接东海岸的yi点,求有多少个交点
题解:
把k条边按照x从小到大排序,如果x相同把y按照从小到大排序,然后利用树状数组求y的逆序数
AC代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
//树状数组求逆序数
#define ll long long
#define maxn 3005
struct node
{
ll a,b;
}temp[maxn*maxn];
ll c[maxn];
bool cmp(node x,node y)
{
if(x.a==y.a)
return x.b<y.b;
return x.a<y.a;
}//排序求交点
ll n,m;
ll lowbit(ll x)
{
return x&(-x);
}
ll update(ll i,ll num)
{
while(i<=m)
{
c[i]+=num;
i+=lowbit(i);
}
}
ll getsum(ll i)
{
ll ans=0;
while(i>0)
{
ans+=c[i];
i-=lowbit(i);
}
return ans;
}
int main()
{
ll t,id=0;
scanf("%lld",&t);
while(t--)
{
memset(c,0,sizeof(c));
ll k;
scanf("%lld %lld %lld",&n,&m,&k);
for(ll i=0;i<k;i++)
{
scanf("%lld %lld",&temp[i].a,&temp[i].b);
}
sort(temp,temp+k,cmp);
ll ans=0;
for(ll i=0;i<k;i++)
{
update(temp[i].b,1);
ans+=getsum(m)-getsum(temp[i].b);
}
printf("Test case %lld: %lld\n",++id,ans);
}
}