1. 程式人生 > >BZOJ4066 簡單題(KD-Tree)

BZOJ4066 簡單題(KD-Tree)

  板子題。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cassert>
using namespace std;
#define ll long long
#define N 200010
#define inf 2000000000
#define lson tree[k].ch[0]
#define rson tree[k].ch[1]
char
getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while
(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,m,root,cnt,c,ans,t,tot,id[N]; const double alpha=0.75; struct point { int d[2],v; bool operator <(const point&a) const { return d[c]<a.d[c]; } }a[N]; struct KDTree{int
ch[2],a[2][2],size,sum;point p; }tree[N]; inline bool isin(point p,int a[2][2]){return p.d[0]>=a[0][0]&&p.d[0]<=a[0][1]&&p.d[1]>=a[1][0]&&p.d[1]<=a[1][1];} inline bool isin(int a[2][2],int b[2][2]){return a[0][0]>=b[0][0]&&a[0][1]<=b[0][1]&&a[1][0]>=b[1][0]&&a[1][1]<=b[1][1];} inline bool iscross(int a[2][2],int b[2][2]){return max(a[0][0],b[0][0])<=min(a[0][1],b[0][1])&&max(a[1][0],b[1][0])<=min(a[1][1],b[1][1]);} void newnode(int k,point p) { tree[k].size=1,tree[k].sum=p.v,tree[k].p=p; tree[k].a[0][0]=tree[k].a[0][1]=p.d[0],tree[k].a[1][0]=tree[k].a[1][1]=p.d[1]; lson=rson=0; } void get(int k) { if (lson) get(lson); t++,id[t]=k,a[t]=tree[k].p; if (rson) get(rson); } void build(int &k,int l,int r,int op) { if (l>r) return; c=op; int mid=l+r>>1; nth_element(a+l,a+mid,a+r+1); newnode(k=id[++tot],a[mid]); for (int i=l;i<=r;i++) tree[k].a[0][0]=min(tree[k].a[0][0],a[i].d[0]),tree[k].a[0][1]=max(tree[k].a[0][1],a[i].d[0]), tree[k].a[1][0]=min(tree[k].a[1][0],a[i].d[1]),tree[k].a[1][1]=max(tree[k].a[1][1],a[i].d[1]); build(lson,l,mid-1,op^1),build(rson,mid+1,r,op^1); tree[k].size+=tree[lson].size,tree[k].size+=tree[rson].size, tree[k].sum+=tree[lson].sum,tree[k].sum+=tree[rson].sum; } void rebuild(int &k,int op) { t=0;get(k); tot=0;build(k,1,t,op); } void ins(int &k,point p,int op) { if (!k) {newnode(k=++cnt,p);return;} if (max(tree[lson].size,tree[rson].size)>tree[k].size*alpha) rebuild(k,op); tree[k].size++;tree[k].sum+=p.v; tree[k].a[0][0]=min(tree[k].a[0][0],p.d[0]),tree[k].a[0][1]=max(tree[k].a[0][1],p.d[0]); tree[k].a[1][0]=min(tree[k].a[1][0],p.d[1]),tree[k].a[1][1]=max(tree[k].a[1][1],p.d[1]); if (tree[k].a[op][1]<=p.d[0]) ins(lson,p,op^1); else ins(rson,p,op^1); } int query(int k,int a[2][2]) { if (!k) return 0; if (isin(tree[k].a,a)) return tree[k].sum; return (isin(tree[k].p,a)?tree[k].p.v:0)+ (iscross(tree[lson].a,a)?query(lson,a):0)+ (iscross(tree[rson].a,a)?query(rson,a):0); } int main() { #ifndef ONLINE_JUDGE freopen("bzoj4066.in","r",stdin); freopen("bzoj4066.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif read();int op=read(); while (op<3) { if (op==1) { int x=read()^ans,y=read()^ans,z=read()^ans; ins(root,(point){{x,y},z},0); } else { int a[2][2];a[0][0]=read()^ans,a[1][0]=read()^ans,a[0][1]=read()^ans,a[1][1]=read()^ans; printf("%d\n",ans=query(root,a)); } op=read(); } return 0; }