Description
Input
Output
Sample Input
1 3 4 4 1 4 2 3 3 2 3 1
Sample Output
Test case 1: 5 求交叉的点数 满足交叉的条件是si<sj&&ei>ej || si>sj&&ei<ej 排好序后就是求终点逆序数了,可以用线段树实现#include<stdio.h> #include<string.h> #include <algorithm> using namespace std; #define N 1010 #define M 1000010 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r int T,n,m,k; int sum[N<<2],a[N]; __int64 ans; struct node { int x; int y; } s[M]; int cmp(node a,node b) { if(a.y!=b.y) return a.y>b.y; return a.x<b.x; } void Pushup(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void Update(int rt,int l,int r,int x) { if(l == r) { sum[rt]++; a[l]++; return ; } int mid = (l + r) >> 1; if(x <= mid) Update(lson,x); else Update(rson,x); Pushup(rt); } int Query(int rt,int l,int r,int L,int R) { if(L <= l && R >= r) { return sum[rt]; } int mid= (l + r) >> 1; int res= 0; if(L <= mid) res += Query(lson,L,R); if(R > mid ) res += Query(rson,L,R); return res; } int main() { int i,j,res,cas = 1; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); memset(sum,0,sizeof(sum)); memset(a,0,sizeof(a)); ans = 0; res = 0; for(i = 1; i <= k; ++i) scanf("%d %d",&s[i].x,&s[i].y); sort(s+1,s+1+k,cmp); for(i = 1; i <= k; ++i) { int tmp = s[i].y; if(i>1 && s[i].y == s[i-1].y) res++; else res = 0; ans += Query(1,1,n,1,s[i].x)-a[s[i].x]-res; Update(1,1,n,s[i].x); } printf("Test case %d: %I64d\n",cas++,ans); } return 0; }
POJ3067:Japan(线段树),布布扣,bubuko.com
原文地址:http://blog.csdn.net/libin56842/article/details/25664691