• AtCoder Beginner Contest 177F


    题:https://atcoder.jp/contests/abc177/tasks/abc177_f

    题意:给定n和m,代表有(n+1)*m的矩阵,有n个询问,每个询问给定a和b,代表在第 i 行的第a列到第b列,不能进行向下操作,其余位置可以进行向下或向右操作,问在给定的限制中,从第1行的任意位置走到第i+1行的最短距离是多少或输出-1表示不能到达。

    分析:对于每个位置的答案,我们建立线段树来记录答案。考虑某个位置pos的答案,肯定是从上一行的左边的某个位置sta能够整体地向右移动pos-sta,再向下移动一个单位,同时保证移动到pos位置是最小的。

       因为这个最小还与位置有关,所以我们再建一棵关于ansi-i的线段树;

       我们可以发现,若能得到终点是a~b的路径,那么答案肯定有比这些路径还小的答案,(a以前),所以每次就把a~b的位置加上无穷大,代表不会取到,其次,若1~b能够到达下一行的b+1~n,那么只需更新b+1位置即可,因为后面位置若通过此方法进行移动,肯定比b+1位置大,所以不用更新。

       最后整体加上1表示向下移动了一步

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    const int M=2e5+5;
    const int inf=0x3f3f3f3f;
    const ll INF=1e18;
    struct Segtree{
        ll tr[M<<2],lz[M<<2];
        void build(int root,int l,int r){
            tr[root]=0,lz[root]=0;
            if(l==r)
                return ;
            int midd=(l+r)>>1;
            build(lson);
            build(rson);
        }
        void pushdown(int root){
            ll c=lz[root];
            tr[root<<1]+=c,tr[root<<1|1]+=c;
            lz[root<<1]+=c,lz[root<<1|1]+=c;
            lz[root]=0;
        }
        void update(int L,int R,ll val,int root,int l,int r){
            if(L<=l&&r<=R){
                tr[root]+=val;
                lz[root]+=val;
                return ;
            }
            if(lz[root])
                pushdown(root);
            int midd=(l+r)>>1;
            if(L<=midd)
                update(L,R,val,lson);
            if(R>midd)
                update(L,R,val,rson);
            tr[root]=min(tr[root<<1],tr[root<<1|1]);
        }
        ll query(int L,int R,int root,int l,int r){
            if(L<=l&&r<=R){
                return tr[root];
            }
            if(lz[root])
                pushdown(root);
            ll res=INF;
            int midd=(l+r)>>1;
            if(L<=midd)
                res=min(res,query(L,R,lson));
            if(R>midd)
                res=min(res,query(L,R,rson));
            return res;
        }
    }x,y;
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        x.build(1,1,m),y.build(1,1,m);
        for(int i=1;i<=m;i++)
            y.update(i,i,-i,1,1,m);
        for(int i=1;i<=n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            ///b+1
            x.update(b+1,b+1,min(1ll*(b+1+y.query(1,b,1,1,m))-x.query(b+1,b+1,1,1,m),0ll),1,1,m);
            y.update(b+1,b+1,min(y.query(1,b,1,1,m)-y.query(b+1,b+1,1,1,m),0ll),1,1,m);
            ///a~b
            x.update(a,b,1e9,1,1,m);
            y.update(a,b,1e9,1,1,m);
            ///向下
            x.update(1,m,1,1,1,m);
            y.update(1,m,1,1,1,m);
            ll ans=x.query(1,m,1,1,m);
            if(ans>=1e9)
                puts("-1");
            else
                printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    前端工程师必备:前端的模块化
    1414. 和为 K 的最少斐波那契数字数目(贪心)
    62. 不同路径(经典dp问题简单路径)
    1051. 高度检查器(排序比较)
    1144. 递减元素使数组呈锯齿状(两次扫)
    面试题 16.04. 井字游戏(模拟即可)
    微信小程序 base64ToArrayBuffer
    人人商城手机端添加控制器
    微擎自定义回复规则
    JS 对浏览器相关的操作
  • 原文地址:https://www.cnblogs.com/starve/p/13585105.html
Copyright © 2020-2023  润新知