zoukankan      html  css  js  c++  java
  • 借教室

    传送门:https://www.luogu.org/problemnew/show/P1083

    先说思路,代码在思路的基础上稍微改了一点,但不难理解。

    【差分】维护一个差分数组,对于每一次借教室,单点修改即可。

    【二分】如果仅仅用差分来解决此题,会严重超时,所以还需要结合二分来看。先判断从1~(1+m)/2天的人借教室是否合法,如果合法了,再去后半部分继续判断;若不合法,则在前半部找到具体是哪个不合法。

    【代码】

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 1e6+1;
    inline int read()
    {
        static char ch;
        while((ch = getchar()) < '0' || ch > '9');
        int ret = ch - 48;
        while((ch = getchar()) >= '0' && ch <= '9')
            ret = ret * 10 + ch - 48;
        return ret;
    }
    int n,m,r[N],d[N],s[N],t[N],a[N],b[N],ans,ll,rr;
    bool check(int mid)
    {
        memset(a,0,sizeof(a));
        for(int i = 1;i <= mid;i++)
        {
            a[s[i]] += d[i];
            a[t[i]+1] -= d[i]; 
        }
        for(int i = 1;i <= n;i++)
        {
            b[i] = b[i-1] + a[i];
            if(b[i] > r[i]) return false;
        }
        return true;
    }
    
    int main()
    {
        n = read();
        m = read();
        for(int i = 1;i <= n;i++) r[i] = read();
        for(int i = 1;i <= m;i++)
            d[i] = read(),s[i] = read(),t[i] = read();
        ll = 1,rr = m,ans = m + 1;
        while(ll <= rr)
        {
            int mid = (ll + rr) >> 1;
            if(check(mid)) ll = mid + 1;
            else 
            {
                rr = mid-1;
                ans = min(ans,mid);
            }
        }
        if(ans == m+1) printf("0");
        else printf("-1
    %d",ans);
        return 0;
    }
  • 相关阅读:
    [HAOI2008]糖果传递
    LGTB 与大数
    LGTB 与序列
    poj1160 Post Office
    组队
    [JLOI2015]装备购买
    三元组
    乘法表
    [BZOJ3730]震波
    [Luogu3345][ZJOI2015]幻想乡战略游戏
  • 原文地址:https://www.cnblogs.com/peppa/p/9837969.html
Copyright © 2011-2022 走看看