• 【BZOJ2626】JZPFAR(KD-Tree)


    点此看题面

    大致题意: 给定(n)个点,每次询问给出一个点问到这个点距离第(k)远的点。

    双倍经验

    说实话没看出这道紫题【BZOJ4520】[CQOI2016] K远点对和此题有什么区别。。。(所以为什么此题就黑了

    同样是求从一个点出发的前(k)大距离,对于每个询问,我们只需要开个小根堆并初始化放入(k)(0),然后就按照(KD-Tree)的套路询问距离。

    不过,此题比上面那题略微烦一些(难道这就是此题是黑题的原因?),由于这题问的是点的编号,因此堆中维护的信息需要开个(struct)记录。还要注意,询问给出的点可能是图上原有的,所以初始化放入的(0)编号要设为(n),否则答案可能会变成(0)

    由于代码是从上面那题复制下来再修改的,所以忘写负数读优WA了一发。。。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define LL long long
    using namespace std;
    int n,D;
    struct data
    {
    	LL v;int p;I data(Con LL& a=0,CI b=0):v(a),p(b){}
    	I bool operator > (Con data& o) Con {return v^o.v?v>o.v:p<o.p;}
    };priority_queue<data,vector<data>,greater<data> > Q;
    struct Point
    {
    	int x[2],id;I Point(CI a=0,CI b=0) {x[0]=a,x[1]=b,id=0;}
    	I int operator [] (CI d) Con {return x[d];}
    	I bool operator < (Con Point& o) Con {return x[D]^o.x[D]?x[D]<o.x[D]:x[D^1]<o.x[D^1];}
    }p[N+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define pc(c) (C==E&&(clear(),0),*C++=c)
    		#define tn (x<<3)+(x<<1)
    		#define D isdigit(c=tc())
    		int f,T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
    	public:
    		I FastIO() {A=B=FI,C=FO,E=FO+FS;}
    		Tp I void read(Ty& x) {x=0,f=1;W(!D) f=c^'-'?1:-1;W(x=tn+(c&15),D);x*=f;}
    		Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
    		Tp I void writeln(Con Ty& x) {write(x),pc('
    ');}
    		I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
    		#undef D
    }F;
    class KDTree//KD-Tree
    {
    	private:
    		#define Gmax(A,B) (A[0]<B[0]&&(A.x[0]=B[0]),A[1]<B[1]&&(A.x[1]=B[1]))
    		#define Gmin(A,B) (A[0]>B[0]&&(A.x[0]=B[0]),A[1]>B[1]&&(A.x[1]=B[1]))
    		#define PU(x)
    		(
    			Mx(x)=V(x),S(x,0)&&Gmax(Mx(x),Mx(S(x,0))),S(x,1)&&Gmax(Mx(x),Mx(S(x,1))),
    			Mn(x)=V(x),S(x,0)&&Gmin(Mn(x),Mn(S(x,0))),S(x,1)&&Gmin(Mn(x),Mn(S(x,1)))
    		)//上传信息
    		int rt,Nt;struct node
    		{
    			#define V(x) O[x].Val
    			#define S(x,d) O[x].Son[d]
    			#define Mx(x) O[x].Max
    			#define Mn(x) O[x].Min
    			int Son[2];Point Val,Max,Min;
    		}O[N+5];
    		I void Build(CI l,CI r,int& rt,Point *P,CI d=0)//建树
    		{
    			int mid=l+r>>1;D=d,nth_element(P+l+1,P+mid+1,P+r+1),V(rt=++Nt)=P[mid],
    			l<mid?(Build(l,mid-1,S(rt,0),P,d^1),0):(S(rt,0)=0),
    			r>mid?(Build(mid+1,r,S(rt,1),P,d^1),0):(S(rt,1)=0),PU(rt);
    		}
    		#define D(A,B) (1LL*(A[0]-B[0])*(A[0]-B[0])+1LL*(A[1]-B[1])*(A[1]-B[1]))//两点间的欧几里得距离的平方
    		#define MxD(x,P)
    			max(1LL*(P[0]-Mn(x)[0])*(P[0]-Mn(x)[0]),1LL*(P[0]-Mx(x)[0])*(P[0]-Mx(x)[0]))+
    			max(1LL*(P[1]-Mn(x)[1])*(P[1]-Mn(x)[1]),1LL*(P[1]-Mx(x)[1])*(P[1]-Mx(x)[1]))//最远距离
    		I void Max(CI rt,Con Point& P)//询问子树更新堆的答案
    		{
    			if(!rt||MxD(rt,P)<Q.top().v) return;//若不可能对答案造成贡献则退出,注意不能取等,除非你还记录并比较编号大小
    			data t=data(D(V(rt),P),V(rt).id);t>Q.top()&&(Q.pop(),Q.push(t),0);//与堆顶比较更新答案
    			RI d=MxD(S(rt,1),P)>=MxD(S(rt,0),P);Max(S(rt,d),P),Max(S(rt,d^1),P);//优先处理可能带来更优答案的子树
    		}
    	public:
    		I void Build(Point *P) {Build(1,n,rt,P);}
    		I void Max(Con Point& P) {Max(rt,P);}
    }K;
    int main()
    {
    	RI i;for(F.read(n),i=1;i<=n;++i) F.read(p[i].x[0]),F.read(p[i].x[1]),p[i].id=i;//读入,记录点的编号
    	RI Qt,x,y,k;K.Build(p),F.read(Qt);W(Qt--)
    	{
    		F.read(x),F.read(y),F.read(k);W(!Q.empty()) Q.pop();//清空原先的堆
    		for(i=1;i<=k;++i) Q.push(data(0,n));K.Max(Point(x,y)),F.writeln(Q.top().p);//加入k个0,询问后输出堆顶
    	}return F.clear(),0;
    }
    
  • 相关阅读:
    编译原理-确定有穷自动机(deterministic finite automata ,DFA)
    编译原理-正规式和正规集
    linux之sed用法
    Linux 中find命令
    运维工作应该掌握哪些技能?
    Last_SQL_Error: Error 'Can't drop database
    关于在centos下安装python3.7.0以上版本时报错ModuleNotFoundError: No module named '_ctypes'的解决办法
    python3.7安装, 解决pip is configured with locations that require TLS/SSL问题
    Linux date命令的用法(转)
    MySQL回滚到某一时刻数据的方法
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2626.html
Copyright © 2020-2023  润新知