• [USACO18FEB]Slingshot


    题意可化为:

    在二维平面中有n个点,坐标为((x_i,y_i)),点权为(t_i)

    现有m个询问,每次给定点((x,y)),求(min{|x-x_i|+|y-y_i|+t_i,|y-x|})

    排序离散化后扫描线+分类讨论即可

    #include"cstdio"
    #include"cstring"
    #include"iostream"
    #include"algorithm"
    using namespace std;
    
    const int MAXN=1<<18;
    const long long INF=1ll<<62;
    
    int n,m,mx;
    long long ans[MAXN];
    long long tree[2][MAXN<<1];
    struct rpg{
    	int x,y;
    	long long t;
    	int id,rey;
    }a[MAXN];
    
    inline int read()
    {
    	int x=0;char ch=getchar();
    	while(ch<'0'||'9'<ch) ch=getchar();
    	while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    	return x;
    }
    
    bool cmp1(rpg a,rpg b){return a.y<b.y;}
    bool cmp2(rpg a,rpg b){return a.x<b.x;}
    
    void init()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i) a[i].x=read(),a[i].y=read(),a[i].t=read(),a[i].id=i;
    	for(int i=n+1;i<=n+m;++i) a[i].x=read(),a[i].y=read(),a[i].t=abs(a[i].y-a[i].x),a[i].id=i;
    	sort(a+1,a+n+m+1,cmp1);a[1].rey=1;
    	for(int i=2;i<=n+m;++i) a[i].rey=a[i].y==a[i-1].y?a[i-1].rey:a[i-1].rey+1;
    	mx=a[n+m].rey;
    	return;
    }
    
    void cchg(int k,int l,int r,int v,int id,bool kd)
    {
    	if(l==r){
    		if(!kd) tree[0][k]=min(tree[0][k],a[id].y-a[id].x+a[id].t),tree[1][k]=min(tree[1][k],a[id].t-a[id].x-a[id].y);
    		else tree[0][k]=min(tree[0][k],a[id].x+a[id].y+a[id].t),tree[1][k]=min(tree[1][k],a[id].x-a[id].y+a[id].t);
    		return;
    	}int i=k<<1,mid=l+r>>1;
    	if(v<=mid) cchg(i,l,mid,v,id,kd);
    	else cchg(i|1,mid+1,r,v,id,kd);
    	tree[0][k]=min(tree[0][i],tree[0][i|1]);
    	tree[1][k]=min(tree[1][i],tree[1][i|1]);
    	return;
    }
    
    long long cask(int k,int l,int r,int le,int ri,bool kd)
    {
    	if(le<=l&&r<=ri) return tree[kd][k];
    	int i=k<<1,mid=l+r>>1;long long mi=INF;
    	if(le<=mid) mi=min(mi,cask(i,l,mid,le,ri,kd));
    	if(mid<ri) mi=min(mi,cask(i|1,mid+1,r,le,ri,kd));
    	return mi;
    }
    
    void solve()
    {
    	sort(a+1,a+n+m+1,cmp2);
    	memset(tree,0x7f,sizeof(tree));
    	int ct1=1,ct2=0;
    	while(ct1<=n+m){
    		while(ct2+1<=n+m&&a[ct2+1].x==a[ct1].x){
    			++ct2;
    			if(a[ct2].id<=n) cchg(1,1,mx,a[ct2].rey,ct2,0);
    		}for(int i=ct1;i<=ct2;++i) if(a[i].id>n) a[i].t=min(a[i].t,min(cask(1,1,mx,1,a[i].rey,1)+a[i].y,cask(1,1,mx,a[i].rey,mx,0)-a[i].y)+a[i].x);
    		ct1=ct2+1;
    	}memset(tree,0x7f,sizeof(tree));
    	ct1=n+m,ct2=n+m+1;
    	while(ct1){
    		while(ct2-1&&a[ct2-1].x==a[ct1].x){
    			--ct2;
    			if(a[ct2].id<=n) cchg(1,1,mx,a[ct2].rey,ct2,1);
    		}for(int i=ct2;i<=ct1;++i) if(a[i].id>n) a[i].t=min(a[i].t,min(cask(1,1,mx,1,a[i].rey,1)+a[i].y,cask(1,1,mx,a[i].rey,mx,0)-a[i].y)-a[i].x);
    		ct1=ct2-1;
    	}for(int i=1;i<=n+m;++i) if(a[i].id>n) ans[a[i].id-n]=a[i].t;
    	for(int i=1;i<=m;++i) printf("%lld
    ",ans[i]);
    	return;
    }
    
    int main()
    {
    	init();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    tif文件导入postgresql
    与你相遇好幸运,使用redis设置定时任务
    用sinopia搭建npm私服
    Postman设置Header不生效问题
    iOS 动态加载LaunchScreen上的图片
    iOS 封装一个带复制功能的UILabel
    ios开发文字排版,段落排版,富文本
    iOS使用hitTest和loadView处理UIView事件传递
    iOS 更改状态栏颜色和隐藏状态栏
    iOS scrollView嵌套tableView的手势冲突解决方案
  • 原文地址:https://www.cnblogs.com/AH2002/p/10208475.html
Copyright © 2020-2023  润新知