codevs 1217 借教室

Posted on 2016-05-05 16:44  ziliuziliu  阅读(111)  评论(0编辑  收藏  举报

差分思想:考虑[l,r]借d个教室,那么让s[l]+=d,s[r+1]-=d,然后对s求一遍前缀和,就是每天的情况,就可以判断是否超出。

然后可以二分。

线段树最多95 23333333......

其实是抄的黄学长的代码。。。不想写了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,ans,a[1000010],d[1000010],x[1000010],y[1000010],s[1000010],sum;
template <class T> T get(T &u){
char x;for(;!isdigit(x=getchar()););
for(u=x-48;isdigit(x=getchar());u*=10,u+=(x-48));
ungetc(x,stdin);return u;
}
bool judge(int v)
{
    memset(s,0,sizeof(s));sum=0;
    for(int i=1;i<=v;i++)
    {s[x[i]]+=d[i];s[y[i]+1]-=d[i];}
    for(int i=1;i<=n;i++)
    {
       sum+=s[i];
       if(sum>a[i])return 0;
    }
    return 1;
}
int main()
{
    get(n),get(m);
    for(int i=1;i<=n;i++)get(a[i]);
    for(int i=1;i<=m;i++)
        get(d[i]),get(x[i]),get(y[i]);
    int l=1,r=m;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(!judge(mid)){ans=mid;r=mid-1;}
        else l=mid+1;
    }
    if(!ans)printf("0");
    else printf("-1\n%d\n",ans);
    return 0;
}