poj 3067 Japan

题目大意:

给你k条路径,问这些路径有多少个交点;

解题思路:

开始的时候,我把第二个点降序,第一个点升序排列,但是处理了很久仍然wrong,没有办法,只能换网上的求逆序的方法;
我们用(x,y)描述边;
先将第一个x按升序排列,相同的时候则把y按升序排列,然后按照y的位置一边求逆序,一边更新;
为什么这样处理呢?我们已经将x升序排列了,后面要插入的边的x肯定小于等于前面的x,这样的情况下,我们只要统计出前面边的y大于插入边的y即可;
利用树状数组的sum函数,求出小于当前y坐标的边的个数,假设当前要插入第K个数,因为已经插入K-1个,所以直接用K-1-sum(y)即可;
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 1000010
struct Node{
	int s,e;
	Node(){}
	~Node(){}
	Node(int a,int b):s(a),e(b){}
	bool operator <(const Node &t)const{
		if(s!=t.s)
		return s<t.s;
		else
		return e<t.e;
	}
};
int n,m;
Node node[maxn];
__int64 c[maxn];
int lowbit(int x)
{
	return x&(-x);
}
void updata(int x)
{
	while(x<=m)
	{
		c[x]+=1;
		x+=lowbit(x);
	}
}
__int64 sum(int x)
{
	__int64 ans=0;
	while(x>0)
	{
		ans+=c[x];
		x-=lowbit(x);
	}
	return ans;
}
int main()
{
	int test;
	scanf("%d",&test);
	int tt=1;
	while(test--)
	{
		int k;
		memset(c,0,sizeof(c));
		scanf("%d%d%d",&n,&m,&k);
		for(int i=0;i<k;i++)
		{
			int a,b;
			scanf("%d%d",&a,&b);
			node[i]=Node(a,b);
		}
		sort(node,node+k);
		__int64 cnt=0;
		for(int i=0;i<k;i++)
		{
			cnt+=i-sum(node[i].e);
			updata(node[i].e);
		}
		printf("Test case %d: %I64d\n",tt++,cnt);
	}
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值