• P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治+欧几里得距离)


    P4169 [Violet]天使玩偶/SJY摆棋子(CDQ分治+欧几里得距离)

    记得上一次欧几里得距离的转化是CF1093G Multidimensional Queries,我们使用了点对在四种方向分别考虑并用 \(\max\) 合并的方法解决,现在使用一种类似的方法。

    \(\bigstar\texttt{Trick}\)

    将点对的统计钦定查询点在修改点在右上方,这样两个点之间的距离就是 \((A_x+B_x)-(A_y+B_y)\)

    那么现在只用将图旋转 \(\frac{\pi}{2}\times 4\),就可以覆盖所有情况了。

    对于这道题,怎么提取出左下右上点对呢?CDQ 分治!

    首先的时间限制作为第一维 \(t_1\le t_2\);后面满足 \(x_1\le x_2,y_1\le y_2\)

    四次 CDQ 即可!

    // Author:A weak man named EricQian
    #include<bits/stdc++.h>
    using namespace std;
    #define infll 0x3f3f3f3f3f3f3f3f
    #define inf 0x3f3f3f3f
    #define Maxn 2000005
    #define pb push_back
    #define pa pair<int,int>
    #define fi first
    #define se second
    typedef long long ll;
    inline int rd()
    {
    	int x=0;
    	char ch,t=0;
    	while(!isdigit(ch = getchar())) t|=ch=='-';
    	while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
    	return x=t?-x:x;
    }
    inline ll maxll(ll x,ll y){ return x>y?x:y; }
    inline ll minll(ll x,ll y){ return x<y?x:y; }
    inline ll absll(ll x){ return x>0ll?x:-x; }
    inline ll gcd(ll x,ll y){ return (y==0)?x:gcd(y,x%y); }
    int n,m,MAX;
    struct QUERY
    {
    	int num,opt,x,y,ans;
    	QUERY(int N=0,int O=0,int X=0,int Y=0,int A=inf):
    		num(N),opt(O),x(X),y(Y),ans(A){}
    }q[Maxn<<1];
    bool operator >= (QUERY a,QUERY b)
    	{ return (a.x!=b.x)?(a.x>=b.x):(a.y>=b.y); }
    bool cmpnum(QUERY x,QUERY y) { return x.num>y.num; }
    bool cmpx(QUERY x,QUERY y) { return (x.x!=y.x)?(x.x>y.x):(x.y>y.y); }
    struct BIT
    {
    	int MIN[Maxn];
    	inline void init(){ memset(MIN,0x3f,sizeof(MIN)); }
    	inline void add(int x,int val)
    		{ while(x<=1000005) MIN[x]=min(MIN[x],val),x+=x&(-x); }
    	inline void del(int x)
    		{ while(x<=1000005) MIN[x]=inf,x+=x&(-x); }
    	inline int query(int x)
    		{ int ret=inf; while(x) ret=min(ret,MIN[x]),x-=x&(-x); return ret; }
    }T;
    inline void Turn()
    {
    	for(int i=1;i<=MAX;i++)
    	{
    		int x=q[i].x,y=q[i].y;
    		q[i].x=1000005-y+1,q[i].y=x;
    	}
    }
    void solve(int nl,int nr)
    {
    	if(nl==nr) return;
    	int mid=(nl+nr)>>1;
    	solve(nl,mid),solve(mid+1,nr);
    	sort(q+nl,q+mid+1,cmpx),sort(q+mid+1,q+nr+1,cmpx);
    	int L=nl,R=mid;
    	for(;L<=mid;L++)
    	{
    		if(q[L].opt==1) continue;
    		while(R<nr && q[R+1]>=q[L])
    		{
    			R++;
    			if(q[R].opt==2) continue;
    			T.add(1000005-q[R].y+1,q[R].x+q[R].y);
    		}
    		q[L].ans=min(q[L].ans,T.query(1000005-q[L].y+1)-q[L].x-q[L].y);
    	}
    	for(int i=mid+1;i<=R;i++)
    	{
    		if(q[i].opt==2) continue;
    		T.del(1000005-q[i].y+1);
    	}
    }
    int main()
    {
    	//ios::sync_with_stdio(false); cin.tie(0);
    	//freopen(".in","r",stdin);
    	//freopen(".out","w",stdout);
    	n=rd(),m=rd(),T.init();
    	for(int i=1,x,y;i<=n;i++) x=rd()+1,y=rd()+1,q[++MAX]=QUERY(0,1,x,y);
    	for(int i=1,opt,x,y;i<=m;i++)
    		opt=rd(),x=rd()+1,y=rd()+1,q[++MAX]=QUERY(i,opt,x,y);
    	for(int tu=1;tu<=4;tu++,Turn()) sort(q+1,q+MAX+1,cmpnum),solve(1,MAX);
    	sort(q+1,q+MAX+1,cmpnum);
    	for(int i=MAX;i>=1;i--) if(q[i].opt==2) printf("%d\n",q[i].ans);
    	//fclose(stdin);
    	//fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    oracle创建表空间自增长和创建用户
    Cmd Markdown 简明语法手册
    Excel VBA修改不同文件簿sheet页名字
    常用JS(JQ)插件研究
    CSS颜色大全(转载)
    React框架学习
    不同浏览器中空格符的兼容问题
    VHDL----基础知识1
    串口通讯1---单片机
    Qt5 程序发布打包
  • 原文地址:https://www.cnblogs.com/EricQian/p/16293783.html
Copyright © 2020-2023  润新知