• 借教室


    题目的意思是只需要找一个人就可以了,还以为要找所有的人,怎么看也看不懂。

    这道题懂的不是很彻底,挖

    我们利用一个差分数组(差分数组:我们能在O(1)的时间内修改一段区间的值)

    举个例子:来自hzwer

    比如一开始数列a是0 0 0 0 0 0

    前缀和0 0 0 0 0 0

    3到5天需要2的教室

    将a[3]+=2,a[6]-=2

    数列变为0 0 2 0 0 -2

    前缀和变为0 0 2 2 2 0

    这样我们就很方便的修改了一段区间的值,当我们要查询一个点上的值,只需要求出其前缀和就行了

    然后二分前mid  个人,这里满足单调性,只有一个是不满足的,并且我们可以知道是在我们的左边还是不在,那么这就和lower_bound查找差不多了,这个数比我小,那么我就在右边,这个数比我大,那么我就在左边

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 1000010
    using namespace std;
    int n,m;
    int d[N],a[N],s[N],t[N],r[N];
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f*=-1;c=getchar();}
        while(c>='0'&&c<='9'){x*=10;x+=c-'0';c=getchar();}
        return x*f;
    }
    bool C(int x)
    {
        int tot=0;
        memset(a,0,sizeof(a));    
        for(int i=1;i<=x;i++) 
        {
            a[s[i]]+=d[i]; a[t[i]+1]-=d[i];
        }
        for(int i=1;i<=n;i++) 
        {
            tot+=a[i]; if(tot>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();
        }
        int l=1,r=m,ans=-1;
        while(l<r-1)
        {
            int mid=(l+r)/2;
            if(C(mid)) l=mid; 
            else {ans=mid;r=mid;}
        }
        if(ans==-1) printf("0"); 
        else printf("-1
    %d",ans);
        return 0;
    }

     

  • 相关阅读:
    项目冲刺——第三篇
    项目冲刺——第五篇
    项目冲刺——第四篇
    团队作业第3周——需求改进&系统设计
    复审与事后分析
    事后诸葛亮分析报告
    团队作业第5周——测试与发布(Alpha版本)
    第四周进销存管理系统冲刺博客汇总
    第三篇 进销存管理系统冲刺博客
    团队作业第3周——需求改进&系统设计
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6058607.html
Copyright © 2020-2023  润新知