bzoj2716/2648 / P4169 [Violet]天使玩偶/SJY摆棋子

P4169 [Violet]天使玩偶/SJY摆棋子

k-d tree 模板

找了好几天才发现输出优化错了....真是zz......

当子树非常不平衡时,就用替罪羊树的思想,拍扁重建。

luogu有个点开了O2才过.......

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cctype>
  6 using namespace std;
  7 char c;void read(int &x){
  8     c=getchar();x=0;int f=1;
  9     while(!isdigit(c)) c=getchar(),f=(f&&c!='-');
 10     while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
 11     x=f?x:-x;
 12 }
 13 void print(int x){
 14     if(x<0) putchar('-'),x=-x;
 15     if(x>9) print(x/10);
 16     putchar(x%10+48);
 17 }
 18 inline int max(int a,int b){return a>b?a:b;}
 19 inline int min(int a,int b){return a<b?a:b;}
 20 inline int abs(int a){return a<0?-a:a;}
 21 #define N 1000010
 22 #define alph (0.75)
 23 #define inf 1e9+7
 24 int n,m,rt,u,ans;
 25 int lit[N],tp1,tp2;
 26 int d;struct node{
 27     int p[2];
 28     void init(){read(p[0]);read(p[1]);}
 29     bool operator < (const node &t) const{
 30         return p[d]<t.p[d];
 31     }
 32 }b[N];
 33 struct data{int mx[2],my[2],ch[2],sz,fa;node ad;}a[N];
 34 #define lc a[o].ch[0]
 35 #define rc a[o].ch[1]
 36 inline void up(int o){  
 37     a[o].mx[0]=max(a[o].mx[0],max(a[lc].mx[0],a[rc].mx[0]));
 38     a[o].mx[1]=min(a[o].mx[1],min(a[lc].mx[1],a[rc].mx[1]));
 39     a[o].my[0]=max(a[o].my[0],max(a[lc].my[0],a[rc].my[0]));
 40     a[o].my[1]=min(a[o].my[1],min(a[lc].my[1],a[rc].my[1]));
 41     a[o].sz=a[lc].sz+a[rc].sz+1;
 42 }
 43 inline void news(int &o,node w){
 44     o=tp1?lit[tp1--]:++u; a[o].ad=w;
 45     lc=rc=0; a[o].sz=1;
 46     a[o].mx[0]=a[o].mx[1]=w.p[0];
 47     a[o].my[0]=a[o].my[1]=w.p[1];
 48 }
 49 void build(int &o,int l,int r,int wd){
 50     if(l>r) return ;
 51     int mid=l+((r-l)>>1);
 52     d=wd;nth_element(b+l,b+mid,b+r+1);
 53     news(o,b[mid]);
 54     build(lc,l,mid-1,wd^1),a[lc].fa=o;
 55     build(rc,mid+1,r,wd^1),a[rc].fa=o;
 56     up(o);
 57 }
 58 void pia(int o){
 59     if(lc) pia(lc);
 60     lit[++tp1]=o; b[++tp2]=a[o].ad;
 61     if(rc) pia(rc);
 62 }
 63 inline void check(int &o,int wd){
 64     if(alph*a[o].sz<max(a[lc].sz,a[rc].sz))
 65         tp2=0,pia(o),build(o,1,tp2,wd);
 66 }//是否不平衡需要重建
 67 void ins(int &o,int wd,node w){
 68     if(!o) {news(o,w); return ;}
 69     d=wd;ins(a[o].ch[a[o].ad<w],wd^1,w);
 70     up(o);check(o,wd);
 71 }
 72 inline int gdis(int o,node w){
 73     if(!o) return inf;
 74     int res=0;
 75     if(w.p[0]>a[o].mx[0]) res+=w.p[0]-a[o].mx[0];
 76     if(w.p[0]<a[o].mx[1]) res+=a[o].mx[1]-w.p[0];
 77     if(w.p[1]>a[o].my[0]) res+=w.p[1]-a[o].my[0];
 78     if(w.p[1]<a[o].my[1]) res+=a[o].my[1]-w.p[1];
 79     return res;
 80 }//点与矩形的最小距离
 81 inline int dis(node A,node B){
 82     return abs(A.p[0]-B.p[0])+abs(A.p[1]-B.p[1]);
 83 }
 84 void query(int o,node w){
 85     if(!o) return ;
 86     ans=min(ans,dis(a[o].ad,w));
 87     int D[2]={gdis(lc,w),gdis(rc,w)},r=D[0]>D[1];
 88     if(D[r]<ans) query(a[o].ch[r],w);
 89     if(D[r^1]<ans) query(a[o].ch[r^1],w);
 90 }
 91 int main(){
 92     read(n);read(m);
 93     a[0].mx[0]=a[0].my[0]=-inf;
 94     a[0].mx[1]=a[0].my[1]=inf;
 95     for(register int i=1;i<=n;++i) b[i].init();
 96     build(rt,1,n,0); node q1;
 97     for(register int i=1,q2;i<=m;++i){
 98         read(q2); q1.init(); 
 99         if(q2==1) ins(rt,0,q1);
100         else{
101             ans=inf,query(rt,q1);
102             print(ans); putchar('\n');
103            }
104     }return 0;
105 }
View Code

 

posted @ 2018-12-19 21:59  kafuuchino  阅读(157)  评论(0编辑  收藏  举报