标签:
啊哈~检验了一下自己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 }
标签:
原文地址:http://www.cnblogs.com/Tunix/p/4525545.html