HDU5618 & CDQ分治

Description:

  三维数点

Solution:

  第一道cdq分治...感觉还是很显然的虽然题目不能再傻逼了...

Code:

  

/*=================================
# Created time: 2016-04-20 10:00
# Filename: hdu5618.cpp
# Description: 
=================================*/
#define me AcrossTheSky&HalfSummer11  
#include <cstdio>  
#include <cmath>  
#include <ctime>  
#include <string>  
#include <cstring>  
#include <cstdlib>  
#include <iostream>  
#include <algorithm>  
  
#include <set> 
#include <stack>  
#include <queue>  
#include <vector>  
  
#define lowbit(x) (x)&(-x)  
#define Abs(x) ((x) > 0 ? (x) : (-(x)))  
#define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++)  
#define FORP(i,a,b) for(int i=(a);i<=(b);i++)  
#define FORM(i,a,b) for(int i=(a);i>=(b);i--)  
#define ls(a,b) (((a)+(b)) << 1)  
#define rs(a,b) (((a)+(b)) >> 1)  
#define getlc(a) ch[(a)][0]  
#define getrc(a) ch[(a)][1]  
  
#define maxn 101005 
#define maxm 100005 
#define INF 1070000000  
using namespace std;  
typedef long long ll;  
typedef unsigned long long ull;  
  
template<class T> inline  
void read(T& num){  
    num = 0; bool f = true;char ch = getchar();  
    while(ch < '0' || ch > '9') { if(ch == '-') f = false;ch = getchar();}  
    while(ch >= '0' && ch <= '9') {num = num * 10 + ch - '0';ch = getchar();}  
    num = f ? num: -num;  
} 
int outs[100]; 
template<class T> inline 
void write(T x){ 
	if (x==0) {putchar('0'); putchar('
'); return;} 
	if (x<0) {putchar('-'); x=-x;} 
	int num=0; 
	while (x){ outs[num++]=(x%10); x=x/10;} 
	FORM(i,num-1,0) putchar(outs[i]+'0'); putchar('
'); 
} 
/*==================split line==================*/ 
struct Point {
	int x,y,z,id;
}a[maxn],b[maxn];
int ans[maxn],c[maxn],maxa;
bool cmpx(Point a,Point b){
	if (a.x==b.x){
		if (a.y==b.y) return a.z<b.z;
		else return a.y<b.y;
	}
	return a.x<b.x;
}
bool cmpy(Point a,Point b){
	if (a.y==b.y) return a.z<b.z;
	return a.y<b.y;
}
int sum(int x){
	int ret=0;
	while (x>0){
		ret+=c[x];
		x-=lowbit(x);
	}
	return ret;
}
void add(int x,int d){
	while (x<=maxa){
		c[x]+=d;
		x+=lowbit(x);
	}
}	
void cdq(int l,int r){
	int m=rs(l,r);
	if (l==r) return;
	int cnt=0;
	FORP(i,l,m) b[++cnt]=a[i],b[cnt].id=b[cnt].x=0;
	FORP(i,m+1,r) b[++cnt]=a[i];
	sort(b+1,b+1+cnt,cmpy);
	FORP(i,1,cnt) 
		if (!b[i].id) add(b[i].z,1);
			else ans[b[i].id]+=sum(b[i].z);
	FORP(i,1,cnt) if (!b[i].id) add(b[i].z,-1);
	cdq(l,m); cdq(m+1,r);
}
int main(){
	int cas; read(cas);
	while (cas--){
		int n; read(n);
		memset(ans,0,sizeof(ans));
		FORP(i,1,n) { a[i].id=i; read(a[i].x); read(a[i].y); read(a[i].z); maxa=max(maxa,a[i].z); }
		sort(a+1,a+1+n,cmpx);
		int cnt=0;
		FORM(i,n,1) {
			if (a[i+1].x==a[i].x && a[i+1].y==a[i].y && a[i+1].z==a[i].z) cnt++;
			else cnt=0;
			ans[a[i].id]+=cnt;
		}
		cdq(1,n);
		FORP(i,1,n) write(ans[i]);
	}
}
原文地址:https://www.cnblogs.com/YCuangWhen/p/5411529.html