给出东西两岸的城市,然后再给出他们之间修建高速的对应关系,求出所有高速路交叉的点的个数...
简单树状数组题,这次用线段树做一下吧,首先把左边的坐标按照降序排列,来更新右边坐标 ,顺遍这题来弄个线段树模版吧
#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;
}

浙公网安备 33010602011771号