zoukankan      html  css  js  c++  java
  • ABC 177 F

    题目:传送门

    题意

    在 n + 1 行,m 列矩阵里,你起初在第 1 行的某一列上,你只能向右或者向下移动,输出 n 行,第 i 行,代表你从第 1 行,移动到第 i + 1 行的最少步数,每一行的第 a[i] ~ b[i] 列的位置都不能向下移动。

    思路

    mp[ i ] 表示 i 这个点,可以从第一行的 mp[i] 移动得到,且 mp[i] 是所有能移动到 i 的点中最靠近 i 的。

    cnt[ i ] 表示,向右移动了 i 的点的个数。

    对于每一行,那些介于 a[i] ~ b[i] 的点都不能向下,那在下一行的 a[i] ~ b[i] 的点都步数通过这一行的点直接向下到达的,那这些点可以暂时删去。

    然后,更新一下 mp[ b[i] + 1 ],如果 b[i] + 1 这个点之前被删了,那现在就是重新加进来了,对于 b[i] + 1 之后的点就无需更新了,因为肯定没有 b[i] + 1 优。

    #include <bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define UI unsigned int
    #define mem(i, j) memset(i, j, sizeof(i))
    #define rep(i, j, k) for(int i = j; i <= k; i++)
    #define dep(i, j, k) for(int i = k; i >= j; i--)
    #define pb push_back
    #define make make_pair
    #define INF 0x3f3f3f3f
    #define inf LLONG_MAX
    #define PI acos(-1)
    #define fir first
    #define sec second
    #define lb(x) ((x) & (-(x)))
    #define dbg(x) cout<<#x<<" = "<<x<<endl;
    using namespace std;
    
    const int N = 1e6 + 5;
    
    int n, m, l[N], r[N], cnt[N];
    
    map < int, int > mp;
    
    void solve() {
    
        scanf("%d %d", &n, &m);
    
        rep(i, 1, n) scanf("%d %d", &l[i], &r[i]);
    
        rep(i, 0, m - 1) mp[i] = i;
    
        cnt[0] = m;
    
        int ans = 0;
    
        rep(i, 1, n) {
    
            l[i]--; r[i]--;
    
            auto it = mp.lower_bound(l[i]);
    
            int pos = -1;
    
            while(it != mp.end() && it->fir <= r[i] + 1) {
    
                pos = max(pos, it->sec);
    
                cnt[it->fir - it->sec]--;
    
                it = mp.erase(it);
    
            }
    
            if(pos >= 0 && r[i] + 1 < m) {
    
                mp[r[i] + 1] = pos; 
    
                cnt[r[i] + 1 - pos]++;
    
            }
    
            while(!cnt[ans] && ans < m) ans++;
    
            if(ans == m) puts("-1");
    
            else printf("%d
    ", i + ans);
    
        }
    
    }
    
    
    int main() {
    
    //    int _; scanf("%d", &_);
    //    while(_--) solve();
    
        solve();
    
        return 0;
    }
  • 相关阅读:
    排序(六)插入排序
    集合类 collection接口 ArrayList
    面向对象四大特性
    多线程 interrupt()方法
    NIO Channel 管道
    NIOBuffer 缓冲区
    lamdba表达式
    cloneable以及深拷贝和浅拷贝
    Volatile关键字
    线程池
  • 原文地址:https://www.cnblogs.com/Willems/p/13589509.html
Copyright © 2011-2022 走看看