首页 > 代码库 > 【NOIP】提高组2012 借教室

【NOIP】提高组2012 借教室

【算法】线段树||二分+前缀和

【题解】二分前缀和写法:http://hzwer.com/2959.html

技术分享
#include<cstdio>#include<algorithm>using namespace std;const int maxn=1e6;struct treess{int l,r,ms,delta;}t[maxn*3];int a[maxn],n,m;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=x*10+c-0;         c=getchar();     }    return x*f;}void build(int k,int l,int r){    t[k].l=l;t[k].r=r;    if(l==r){t[k].ms=a[l];return;}    int mid=(l+r)>>1;    build(k<<1,l,mid);    build(k<<1|1,mid+1,r);    t[k].ms=min(t[k<<1].ms,t[k<<1|1].ms);}void update(int k,int l,int r,int num){    int left=t[k].l,right=t[k].r;    if(l<=left&&r>=right)     {//         t[k].ms-=num;         t[k].delta+=num;     }    else     {        int mid=(left+right)>>1;        if(l<=mid)update(k<<1,l,r,num);        if(r>mid)update(k<<1|1,l,r,num);        t[k].ms=min(t[k<<1].ms-t[k<<1].delta,t[k<<1|1].ms-t[k<<1|1].delta);     }}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)a[i]=read();    build(1,1,n);    for(int i=1;i<=m;i++)     {         int d=read(),s=read(),t_=read();         update(1,s,t_,d);         if(t[1].ms-t[1].delta<0)          {              printf("-1\n%d",i);              return 0;          }     }    printf("0");    return 0;}
View Code

 

【NOIP】提高组2012 借教室