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;
}
相关文章推荐
- java中String类型的最大长度
- 大型网站架构模式
- [ActionScript 3.0] AS3 绘制立方体
- java 截取汉字
- 个性化WinPE封装方法《第二讲----添加应用程序》
- Android 最火的快速开发框架XUtils
- 给超链接加onclick事件
- spring aop邮件发送
- android屏幕适配详解
- 匿名内部类调用构造方法的原理
- 个性化WinPE封装方法《第一讲----整体思路》
- DP - hdu5001 Walk
- curl 命令的使用
- Javascript dom结点操作总结
- nil/Nil/NULL/NSNull的区别
- Android(java)学习笔记204:自定义SmartImageView(继承自ImageView,扩展功能为自动获取网络路径图片)
- Android 清理应用缓存
- 解决Win10下安装office2013问题
- 软件测试实训1
- poj 3621 Sightseeing Cows 【最优比例环】 【0-1分数规划 + SPFA判负环】