zoukankan      html  css  js  c++  java
  • 洛谷P4088 [USACO18FEB]Slingshot

    题面

    大意:给出n个弹弓,可以用ti的时间把xi位置运到yi,在给出m组询问,求xj到yj最小时间。

    sol:首先如果不用弹弓,时间应为abs(xj-yj)。否则时间就是abs(xi-xj)+abs(yi-yj)+ti。这就需要拆开绝对值用线段树来维护了。大力枚举四种情况,建四次线段树,就可以过了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define int long long
    const int N=200005,inf=0x7fffffffffffff;
    int n,m,cnt=0,nn,hax[N],hay[N],ans[N];
    struct node{int x,y,t,id;}p[N];
    inline bool cmp(node aa,node bb){return (aa.x!=bb.x)?(aa.x<bb.x):(aa.y<bb.y);}
    struct segtree{int l,r,mi;inline int mid(){return (l+r)>>1;}}Tree[N<<2];
    #define c1 x<<1
    #define c2 x<<1|1
    inline void Up(int x){Tree[x].mi=min(Tree[c1].mi,Tree[c2].mi);}
    inline void build(int l,int r,int x){Tree[x].l=l;Tree[x].r=r;if(l==r){Tree[x].mi=inf;return;}int mid=(l+r)>>1;build(l,mid,c1);build(mid+1,r,c2);Up(x);}
    inline void ins(int x,int po,int v){if(Tree[x].l==Tree[x].r){Tree[x].mi=min(Tree[x].mi,v);return;}int mid=Tree[x].mid();if(po<=mid)ins(c1,po,v);else ins(c2,po,v);Up(x);}
    inline int que(int l,int r,int x){if(Tree[x].l==l&&Tree[x].r==r)return Tree[x].mi;int mid=Tree[x].mid();if(r<=mid)return que(l,r,c1);else if(l>mid)return que(l,r,c2);else return min(que(l,mid,c1),que(mid+1,r,c2));}
    signed main()
    {
        freopen("1.in","r",stdin);
        int i,x,y,t; scanf("%lld%lld",&n,&m);
        for(i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld",&x,&y,&t); p[++cnt]=(node){x,y,t,0}; hax[cnt]=x; hay[cnt]=y;
        }
        for(i=1;i<=m;i++)
        {
            scanf("%lld%lld",&x,&y); p[++cnt]=(node){x,y,0,i}; hax[cnt]=x; hay[cnt]=y; ans[i]=abs(x-y);
        }sort(hax+1,hax+cnt+1); sort(hay+1,hay+cnt+1); sort(p+1,p+cnt+1,cmp);
        nn=unique(hax+1,hax+cnt+1)-hax-1; for(i=1;i<=cnt;i++)p[i].x=lower_bound(hax+1,hax+nn+1,p[i].x)-hax;
        nn=unique(hay+1,hay+cnt+1)-hay-1; for(i=1;i<=cnt;i++)p[i].y=lower_bound(hay+1,hay+nn+1,p[i].y)-hay;
        build(1,cnt,1); for(i=1;i<=cnt;i++)if(!p[i].id)ins(1,p[i].y,-hax[p[i].x]-hay[p[i].y]+p[i].t);else ans[p[i].id]=min(ans[p[i].id],que(1,p[i].y,1)+hax[p[i].x]+hay[p[i].y]);
        build(1,cnt,1); for(i=1;i<=cnt;i++)if(!p[i].id)ins(1,p[i].y,-hax[p[i].x]+hay[p[i].y]+p[i].t);else ans[p[i].id]=min(ans[p[i].id],que(p[i].y,cnt,1)+hax[p[i].x]-hay[p[i].y]);
        build(1,cnt,1); for(i=cnt;i>=1;i--)if(!p[i].id)ins(1,p[i].y,+hax[p[i].x]+hay[p[i].y]+p[i].t);else ans[p[i].id]=min(ans[p[i].id],que(p[i].y,cnt,1)-hax[p[i].x]-hay[p[i].y]);
        build(1,cnt,1); for(i=cnt;i>=1;i--)if(!p[i].id)ins(1,p[i].y,+hax[p[i].x]-hay[p[i].y]+p[i].t);else ans[p[i].id]=min(ans[p[i].id],que(1,p[i].y,1)-hax[p[i].x]+hay[p[i].y]);
        for(i=1;i<=m;i++)printf("%lld
    ",ans[i]);
    }
    View Code
  • 相关阅读:
    数学--数论--HDU 2136(素数筛选法)
    思维+模拟--POJ 1013 Counterfeit Dollar
    数学--数论--莫比乌斯函数
    事半功倍和事倍功半
    一道阿里面试题
    文本分类学习(三) 特征权重(TF/IDF)和特征提取
    汉字字典树
    文本分类学习(二)文本表示
    文本分类学习(一):开篇
    一道网易面试编程题
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/9785338.html
Copyright © 2011-2022 走看看