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


    传送门

    用kdtree重新写了一遍
    然后发现kdtree竟然跑的比CDQ快?
    也是很神奇了……

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define inf 0x3f3f3f3f
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R int x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    }
    const int N=1e6+5;const double alph=0.75;
    struct point{int x[2];}p[N];
    struct node{int mn[2],mx[2],ls,rs,sz;point tp;}tr[N];
    int n,m,rt,cur,top,WD,ans,st[N];
    inline bool operator <(point a,point b){return a.x[WD]<b.x[WD];}
    inline int newnode(){return top?st[top--]:++cur;}
    void upd(int p){
    	int l=tr[p].ls,r=tr[p].rs;
    	fp(i,0,1){
    		tr[p].mn[i]=tr[p].mx[i]=tr[p].tp.x[i];
    		if(l)cmin(tr[p].mn[i],tr[l].mn[i]),cmax(tr[p].mx[i],tr[l].mx[i]);
    		if(r)cmin(tr[p].mn[i],tr[r].mn[i]),cmax(tr[p].mx[i],tr[r].mx[i]);
    	}tr[p].sz=tr[l].sz+tr[r].sz+1;
    }
    int build(int l,int r,int wd){
    	if(l>r)return 0;int k=newnode(),mid=(l+r)>>1;
    	WD=wd,nth_element(p+l,p+mid,p+r+1),tr[k].tp=p[mid];
    	tr[k].ls=build(l,mid-1,wd^1),tr[k].rs=build(mid+1,r,wd^1);
    	upd(k);return k;
    }
    void pia(int k,int sum){
    	if(tr[k].ls)pia(tr[k].ls,sum);
    	p[sum+tr[tr[k].ls].sz+1]=tr[k].tp,st[++top]=k;
    	if(tr[k].rs)pia(tr[k].rs,sum+tr[tr[k].ls].sz+1);
    }
    void check(int &p,int wd){
    	if(alph*tr[p].sz<tr[tr[p].ls].sz||alph*tr[p].sz<tr[tr[p].rs].sz)
    	pia(p,0),p=build(1,tr[p].sz,wd);
    }
    void ins(point res,int &p,int wd){
    	if(!p)return (void)(p=newnode(),tr[p].tp=res,tr[p].ls=tr[p].rs=0,upd(p));
    	if(tr[p].tp.x[wd]<res.x[wd])ins(res,tr[p].rs,wd^1);
    	else ins(res,tr[p].ls,wd^1);upd(p),check(p,wd);
    }
    int getdis(point res,int p){
    	int r=0;fp(i,0,1)r+=max(0,res.x[i]-tr[p].mx[i])+max(0,tr[p].mn[i]-res.x[i]);
    	return r;
    }
    int dis(point a,point b){return abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1]);}
    void query(point res,int p){
    	cmin(ans,dis(res,tr[p].tp));
    	int dl=inf,dr=inf;
    	if(tr[p].ls)dl=getdis(res,tr[p].ls);
    	if(tr[p].rs)dr=getdis(res,tr[p].rs);
    	if(dl<dr){
    		if(dl<ans)query(res,tr[p].ls);
    		if(dr<ans)query(res,tr[p].rs);
    	}else{
    		if(dr<ans)query(res,tr[p].rs);
    		if(dl<ans)query(res,tr[p].ls);
    	}
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),m=read();
    	fp(i,1,n)p[i].x[0]=read(),p[i].x[1]=read();
    	rt=build(1,n,0);
    	while(m--){
    		point res;int op=read();res.x[0]=read(),res.x[1]=read();
    		if(op==1)ins(res,rt,0);
    		else ans=inf,query(res,rt),print(ans);
    	}return Ot(),0;
    }
    
  • 相关阅读:
    .Net基础:CLR基本原理
    行业软件开发商怎样来抢 BI 这块蛋糕?
    免费报表工具知多少?
    哪款报表工具更适合行业软件开发商?
    报表如何通过参数控制数据权限
    实现报表滚动到底部翻页效果
    报表 BI 选型的那些事
    零编码制作报表可能吗?
    为什么说当前报表开发的工作量主要在数据源环节?又如何解决呢?
    用存储过程和 JAVA 写报表数据源有什么弊端?
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10085235.html
Copyright © 2020-2023  润新知