• P1083 借教室


    传送门

    最显然的方法就是线段树

    稍微卡一下常就过了

    还有另一种方法,差分

    但是有一个问题,我们怎么知道是谁使订单无法满足呢

    一种直接的想法就是二分

    但是复杂度为 O(nlogm) 跟线段树O(mlogn)一样,但是常数小可过此题

    重点是讲 O(n+m) 的方法

    同样差分,从左到右一个个扫过去

    如果出现了负数就把订单往回撤,一直撤到变成正数,然后继续扫

    扫完后每天都符合要求了,并且如果再多一份订单就会出现负数

    所以最后答案就是撤到的订单编号加1

    撤回过程中的具体操作还是看代码吧

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<map>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=1e6+7;
    int l[N],r[N],d[N],a[N];
    int n,m;
    ll now,tag[N];
    int main()
    {
        n=read(); m=read();
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=m;i++)
        {
            d[i]=read(); l[i]=read(); r[i]=read();
            tag[l[i]]+=d[i]; tag[r[i]+1]-=d[i];
        }
        int pos=m;//记录当前撤回到哪个订单
        for(int i=1;i<=n;i++)
        {
            now+=tag[i];
            while(now>a[i]&&pos)//如果需求超过供给就要往回撤,注意保证pos>0,不然会RE
            {
                tag[l[pos]]-=d[pos]; tag[r[pos]+1]+=d[pos];//撤回订单
                if(l[pos]<=i&&r[pos]>=i) now-=d[pos];//如果有包含当前位置,now也要更新
                pos--;
            }
        }
        if(pos==m) { printf("0"); return 0; }
        printf("-1
    %d",pos+1);
    }
  • 相关阅读:
    springmvc 处理静态资源
    springmvc jsp 获取 上下文
    springmvc 如何设置首页
    servlet-mapping url-pattern / 和 /*区别
    nginx支持php
    openresty 变量
    git tag用法
    python 导入模块,__init__.py 的作用
    python 转码问题
    python装饰器
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9869634.html
Copyright © 2020-2023  润新知