啊哈~检验了一下自己KD-Tree的学习情况,还算可以,模板至少是记下来了。

  支持插入(所以要带重建),查询最近的P个点的距离。

  然而题目并没有说是按怎样的顺序输出这P个点?。。。(事实上是从近到远)

  没啥好讲的……就是KD-Tree的裸操作……

  1     //Tsinsen A1365
  2     #include<cmath>
  3     #include<queue>
  4     #include<vector>
  5     #include<cstdio>
  6     #include<cstring>
  7     #include<cstdlib>
  8     #include<iostream>
  9     #include<algorithm>
 10     #define rep(i,n) for(int i=0;i<n;++i)
 11     #define F(i,j,n) for(int i=j;i<=n;++i)
 12     #define D(i,j,n) for(int i=j;i>=n;--i)
 13     #define pb push_back
 14     using namespace std;
 15     inline int getint(){
 16         int v=0,sign=1; char ch=getchar();
 17         while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
 18         while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
 19         return v*sign;
 20     }
 21     const int N=2e5+10;
 22     typedef long long LL;
 23     const LL INF=1e9;
 24     /******************tamplate*********************/
 25     int n,m,K,P,D,p[N],cnt,tot,root;
 26     struct node{
 27         int d[2],mn[2],mx[2],l,r,D,size;
 28         int& operator [] (int x){return d[x];}
 29         void read(){d[0]=getint();d[1]=getint();}
 30     }t[N],tmp;
 31     inline bool cmp(int x,int y){return t[x][D]<t[y][D];}
 32     #define L t[o].l
 33     #define R t[o].r
 34     #define mid (l+r>>1)
 35     void Push_up(int o){
 36         F(i,0,1){
 37             t[o].mn[i]=min(t[o][i],min(t[L].mn[i],t[R].mn[i]));
 38             t[o].mx[i]=max(t[o][i],max(t[L].mx[i],t[R].mx[i]));
 39         }
 40         t[o].size=t[L].size+t[R].size+1;
 41     }
 42     int build(int l,int r,int dir){
 43         D=dir;
 44         nth_element(p+l,p+mid,p+r+1,cmp);
 45         int o=p[mid];
 46         t[o].D=dir;
 47         L=l<mid?build(l,mid-1,dir^1):0;
 48         R=r>mid?build(mid+1,r,dir^1):0;
 49         Push_up(o);
 50         return o;
 51     }
 52     void dfs(int o){
 53         if (!o) return;
 54         dfs(L);
 55         p[++cnt]=o;
 56         dfs(R);
 57     }
 58     void rebuild(int &o){
 59         cnt=0;
 60         dfs(o);
 61         o=build(1,cnt,t[o].D);
 62     }
 63     void Insert(int &o,int dir){
 64         if (!o){
 65             o=++tot; t[o]=tmp;
 66             F(i,0,1) t[o].mn[i]=t[o].mx[i]=t[o][i];
 67             t[o].D=dir; t[o].size=1;
 68         }else{
 69             if (tmp[dir]<t[o][dir]){
 70                 Insert(L,dir^1); Push_up(o);
 71                 if ((double)t[L].size>(double)t[o].size*0.7) rebuild(o);
 72             }else{
 73                 Insert(R,dir^1); Push_up(o);
 74                 if ((double)t[R].size>(double)t[o].size*0.7) rebuild(o);
 75             }
 76         }
 77     }
 78     inline LL get(LL v){
 79         if (K==1) return abs(v);
 80         else return v*v;
 81     }
 82     inline double ANS(LL v){
 83         if (K==1) return v;
 84         else return sqrt(double(v));
 85     }
 86     inline LL getdis(int o){
 87         if (!o) return 1e16;
 88         LL ans=0;
 89         F(i,0,1){
 90             if (t[o].mn[i]>tmp[i]) ans+=get(t[o].mn[i]-tmp[i]);
 91             if (t[o].mx[i]<tmp[i]) ans+=get(tmp[i]-t[o].mx[i]);
 92         }
 93         return ans;
 94     }
 95     inline LL dis(int o){return get(t[o][0]-tmp[0])+get(t[o][1]-tmp[1]);}
 96     priority_queue<LL>Q;
 97     void query(int o){
 98         if (!o) return;
 99         LL dl=getdis(L),dr=getdis(R),d0=dis(o);
100         if (d0<Q.top()){Q.pop(); Q.push(d0);}
101         if (dl<dr){
102             if (dl<Q.top()) query(L);
103             if (dr<Q.top()) query(R);
104         }else{
105             if (dr<Q.top()) query(R);
106             if (dl<Q.top()) query(L);
107         }
108     }
109     double ans[5];
110     int main(){
111     #ifndef ONLINE_JUDGE
112         freopen("A1365.in","r",stdin);
113         freopen("A1365.out","w",stdout);
114     #endif
115         F(i,0,1) t[0].mn[i]=INF,t[0].mx[i]=-INF;
116         t[0].size=0;
117         tot=n=getint(); m=getint(); K=getint(); P=getint();
118         F(i,1,n) {t[i].read(); p[i]=i;}
119         root=build(1,n,1);
120         char cmd[5];
121         F(i,1,m){
122             scanf("%s",cmd);
123             tmp.read();
124             if (cmd[0]=='Q'){
125                 F(j,1,P) Q.push(1e16);
126                 query(root);
127                 D(j,P,1){
128                     ans[j]=ANS(Q.top());
129                     Q.pop();
130                 }
131                 F(j,1,P)
132                     printf("%.4f%c",ans[j],j==P ? '\n' : ' ');
133             }else{
134                 Insert(root,1);
135             }
136         }
137         return 0;
138     }
View Code

相关文章: