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('\n'); 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('\n');
}
/*==================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]);
}
}
上一篇:[ 随手记 1 ] C/C++宏,普通函数,内联函数


下一篇:svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码