zoukankan      html  css  js  c++  java
  • P1083 [NOIP 2012]借教室

    https://www.luogu.org/problem/show?pid=1083#sub

    一开始容易想到的方法是线段树,每次修改时,如果出现负数,那么当前这个人一定不能满足了。
    但是在noip里,这肯定不是正解,所以会超时那么一两个点。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<stdlib.h>
    #define M 1000000
    using namespace std;
    int n,m,cnt;
    int a[M+100];
    struct H{
        int x,l,r,len,addi;
    }st[5*M];
    inline int read()
    {
        int data=0,w=1; char ch=0;
        while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
        if(ch=='-') w=-1,ch=getchar();
        while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
        return data*w;
    }
    void build(int o,int l,int r)
    {
        st[o].l=l,st[o].r=r,st[o].len=r-l+1;
        if(l==r){st[o].x=a[l];return;}
        int mid=(l+r)>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
        st[o].x=min(st[o<<1].x,st[o<<1|1].x); 
    }
    void pushdown(int o)
    {
        st[o<<1].addi+=st[o].addi;
        st[o<<1|1].addi+=st[o].addi;
        st[o<<1].x+=st[o].addi;
        st[o<<1|1].x+=st[o].addi;   
        st[o].addi=0;
    }
    void add(int o,int ql,int qr,int ax)
    {
        int l=st[o].l,r=st[o].r,mid=(l+r)>>1;
        if(l==ql&&r==qr)
        {
            st[o].addi+=ax;
            st[o].x+=ax;
            if(st[o].x<0)
            {
                printf("-1
    %d",cnt);
                exit(0);
            }
            return;
        }
    
        if(st[o].addi) pushdown(o);
    
        if(qr<=mid) add(o<<1,ql,qr,ax);
        else if(ql>mid) add(o<<1|1,ql,qr,ax);
        else add(o<<1,ql,mid,ax),add(o<<1|1,mid+1,qr,ax);
        st[o].x=min(st[o<<1].x,st[o<<1|1].x);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        build(1,1,n); 
        for(int i=1;i<=m;i++)
        {
            int d,s,t;
            cnt=i;
            //scanf("%d%d%d",&d,&s,&t);
            d=read();
            s=read();
            t=read();
            add(1,s,t,-d);
        }
        printf("0
    ");
        return 0;
    }

    那么正解是什么呢–>二分答案。
    判定的写法是,对前mid个人操作,加上差分,最后看看是否有小于0的,有则r=mid-1,否则l=mid+1;
    这样一直判定。最后如果l>=n,就说明全部都能满足;否则答案就是 l 。

    #include<iostream>
    #include<cstdio>
    #define M 1000000
    using namespace std;
    int n,m,a[M+10],b[M+10];
    int d[M+10],s[M+10],t[M+10];
    bool check(int x)
    {
        for(int i=1;i<=n;i++) b[i]=a[i]-a[i-1];
        for(int i=1;i<=x;i++) b[s[i]]-=d[i],b[t[i]+1]+=d[i];
        for(int i=1;i<=n;i++) {
            b[i]+=b[i-1];
            if(b[i]<0) return false;
        }
        return true;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=m;i++) scanf("%d%d%d",&d[i],&s[i],&t[i]);
        int l=1,r=n,mid;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(check(mid)) l=mid+1;
            else r=mid-1;
        }
        if(l>=n) printf("0");
        else printf("-1
    %d",l);
        return 0;       
    }
  • 相关阅读:
    Head first javascript(七)
    Python Fundamental for Django
    Head first javascript(六)
    Head first javascript(五)
    Head first javascript(四)
    Head first javascript(三)
    Head first javascript(二)
    Head first javascript(一)
    Sicily 1090. Highways 解题报告
    Python GUI programming(tkinter)
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587867.html
Copyright © 2011-2022 走看看