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