• 洛谷p1083借教室


    今天用线段树把这个题又做了一遍,除了代码有点长其他还好,线段树思维不难

    先读入每天提供的教室数,在建树,依次读入每个人的要求,先区间修改,再判断是否合法(注意修改时要变为负数,因为是减去当前值)判断合法直接用tree[1]即可

    #include<bits/stdc++.h>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define maxn 1000001
    using namespace std;
     
    inline int read(){
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
        while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
        return x*f;
    }
     
    int n,m,aa[maxn],tree[maxn<<2],lazy[maxn<<2];
     
    bool ok=1;
     
    void pushup(int rt){
        tree[rt]=min(tree[rt<<1],tree[rt<<1|1]);
    }
     
    void buildtree(int l,int r,int rt){
        if(l==r){
            tree[rt]=aa[l];return;
        }
        int mid=(l+r)>>1;
        buildtree(lson);
        buildtree(rson);
        pushup(rt);
    }
     
    void add(int l,int r,int rt,int delta){
        lazy[rt]+=delta;
        tree[rt]+=delta;
    }
     
    void pushdown(int l,int r,int rt){
        if(!lazy[rt]) return;
        int mid=(l+r)>>1;
        add(lson,lazy[rt]);
        add(rson,lazy[rt]);
        lazy[rt]=0;
    }
     
    void xg(int L,int R,int delta,int l,int r,int rt){
        if(L<=l&&R>=r){
            add(l,r,rt,delta);return ;
        }
        pushdown(l,r,rt);
        int mid=(l+r)>>1;
        if(L<=mid)xg(L,R,delta,lson);
        if(R>mid)xg(L,R,delta,rson);
        pushup(rt);
    }
     
    int main(){
        n=read(),m=read();
        for(int i=1;i<=n;i++){
            aa[i]=read();
        }
        buildtree(1,n,1);
        for(int i=1;i<=m;i++){
            int d=read(),s=read(),t=read();
            xg(s,t,-d,1,n,1);
            if(tree[1]<0) {printf("-1
    %d",i);return 0;
            }
        }
        printf("0");return 0;
    }

    当然还有其他方法,就是我原来时做的(当时线段树基本不会)

    总的来说就是差分+二分(应该叫差分吧,不管了,应该没啥影响)

    先将每个数据存起来,判断是否全都可行,就是把m带入计算,用cf记录差分,操作为:cf[s[i]]+=d[i];cf[t[i]+1]-=d[i];在用need存每天总共所需的need[i]=need[i]+cf[i](妙啊

    如果m不行的话就开始二分,没什么好说的了,上代码

    #include<bits/stdc++.h>
    #define maxm 1000010
    using namespace std;
    
    int d[maxm],s[maxm],t[maxm],r[maxm],cf[maxm],need[maxm],lef=1,rit,n,m;
    
    inline int read()
    {
        int f=1,x=0;char ch=getchar();
        while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
        return f*x;
    } 
    
    bool work(int x)
    {
        memset(cf,0,sizeof(cf));
        for(int i=1;i<=x;i++)
        {
            cf[s[i]]+=d[i];
            cf[t[i]+1]-=d[i];
        }
        for(int i=1;i<=n;i++)
        {
            need[i]=need[i-1]+cf[i];
            if(need[i]>r[i]) return 0;
        }
        return 1;
    }
    
    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();
        }
        rit=m;
        if(work(m)) {printf("0");return 0;}
        while(lef<=rit)
        {
            int mid=(lef+rit)>>1;
            if(work(mid)) lef=mid+1;
            else rit=mid-1;
        }
        printf("-1
    %d",lef);
        return 0;
    } 
  • 相关阅读:
    数据结构之队列
    设计模式之策略模式的使用
    搭建一个高可用的redis环境
    Linux遗忘命令
    重温几种排序算法之希尔排序、归并排序、快速排序
    HashMap的简单实现
    Java GC基础
    2016年年终总结
    Shell 备忘录
    Openstack Grizzily 单节点测试机安装( All In One CentOS/RHEL)
  • 原文地址:https://www.cnblogs.com/plysc/p/10333128.html
Copyright © 2020-2023  润新知