void-man

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

给出东西两岸的城市,然后再给出他们之间修建高速的对应关系,求出所有高速路交叉的点的个数...

简单树状数组题,这次用线段树做一下吧,首先把左边的坐标按照降序排列,来更新右边坐标 ,顺遍这题来弄个线段树模版吧

#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
using namespace std;
const int MAX = 32010;
struct Tnode{ int l,r,val;};
Tnode node[MAX<<2];
struct nodes{int x,y;}a[1010000];
__int64 ans;
void init()
{
	memset(node,0,sizeof(node));
	ans=0;

}

void build(int t,int l,int r)
{
	node[t].l = l; node[t].r = r;
	node[t].val = 0;
	if( node[t].l == node[t].r - 1 )
		return ;
	int mid = MID(l,r);
	build(L(t),l,mid);
	build(R(t),mid,r);
}

void update(int t,int l,int r)
{
	if( node[t].l >= l && node[t].r <= r )
	{
		node[t].val++;
		return ;
	}
	if( node[t].l == node[t].r - 1 ) return ;
	int mid = MID(node[t].l,node[t].r);
	if( l <= mid )
		update(L(t),l,r);
	if( r > mid )
		update(R(t),l,r);
	node[t].val = node[R(t)].val + node[L(t)].val;
}

int get(int t,int l,int r)
{
	if( node[t].l >= l && node[t].r <= r )
		return node[t].val;
    if( node[t].l == node[t].r - 1 ) return 0;
	int ans = 0;
	int mid = MID(node[t].l,node[t].r);
	if( l <= mid ) ans += get(L(t),l,r);
	if( r > mid ) ans += get(R(t),l,r);
	return ans;
}
bool cmp(nodes a,nodes b)
{
    if(a.x==b.x)return a.y>b.y;
    return a.x>b.x;

}
int main()
{
	int n,m,k,t,ca=1;
    scanf("%d",&t);
	while( t-- )
	{
		init();
		scanf("%d%d%d",&n,&m,&k);
		int mmax = max(n,m);
		for(int i=0; i<k; i++)
		{
			scanf("%d%d",&a[i].x,&a[i].y);
		}
		sort(a,a+k,cmp);
		build(1,0,mmax+1);
		for(int i=0; i<k; i++)
		{
			 ans += get(1,0,a[i].y);
			 update(1,a[i].y,a[i].y+1);
		}
		printf("Test case %d: %I64d\n",ca++,ans);

	}
return 0;
}
posted on 2011-08-06 23:38  void-man  阅读(309)  评论(1)    收藏  举报