您的位置:首页 > 其它

poj3067 Japan (树状数组)

2015-09-02 17:12 162 查看

题目大意

左边有n个点,从上到下依次为1、2、3、......、n-1、n

右边有m个点,从上到下一次为1、2、3、.......、m-1、m

然后有k条路,分别连接左右两边的点。

求这些路之间的交点有多少。每个交点至多被两条路径经过。

这一题的做法:

这一题其实就是求逆序对的稍微变化。只要将k个路径按照:x大的大,若x相等则y大的大。

代码:

booloperator<(constroad&a,constroad&b)
{
if(a.x==b.x)
returna.y>b.y;
elsereturna.x>b.x;
}

然后从大到小求a[i].y的逆序对即可

代码:

for(i=1;i<=k;i++)
{
ans+=1ll*query(a[i].y-1);
updata(a[i].y,1);
}


全部代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string>
#include<string.h>
usingnamespacestd;

constintMAXN=1000+100;
classroad
{
public:
intx,y;
};
booloperator<(constroad&a,constroad&b)
{
if(a.x==b.x)
returna.y>b.y;
elsereturna.x>b.x;
}

inth[MAXN];
roada[MAXN*MAXN];
longlongans;
intn,m,k;

intlowbit(intx)
{
returnx&(-x);
}
intquery(intx)
{
intans=0;
while(x>0)
{
ans+=h[x];
x-=lowbit(x);
}
returnans;
}
voidupdata(intx,intval)
{
while(x<=m)
{
h[x]+=val;
x+=lowbit(x);
}
}
intmain()
{
intT,i,x,y,tt=0;
scanf("%d",&T);
while(T--)
{
ans=0;
tt++;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=k;i++)
{
scanf("%d%d",&x,&y);
a[i].x=x;
a[i].y=y;
}
sort(a+1,a+k+1);
memset(h,0,sizeof(h));
for(i=1;i<=k;i++)
{
ans+=1ll*query(a[i].y-1);
updata(a[i].y,1);
}
printf("Testcase%d:%lld\n",tt,ans);
}
return0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: