zoukankan      html  css  js  c++  java
  • LUOGU P1083 借教室

    传送门

    解题思路

    正解好像是什么前缀和+二分,没想到。。就写了个线段树骗分,结果擦着边过了??线段树中维护一个区间和 and 最小值即可。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    
    using namespace std;
    const int MAXN = 1e6+5;
    typedef long long LL;
    
    int n,m,a[MAXN],d[MAXN],s[MAXN],t[MAXN];
    LL sum[MAXN<<1];
    int lazy[MAXN<<1],mn[MAXN<<1],ans;
    bool flag;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    inline int min(int x,int y){
        return x>y?y:x;
    }
    
    inline void build(int x,int l,int r){
        if(l==r){
            sum[x]=a[l];
            mn[x]=a[l];
            return ;
        }
        int mid=l+r>>1;
        build(x<<1,l,mid);
        build(x<<1|1,mid+1,r);
        sum[x]=sum[x<<1]+sum[x<<1|1];
        mn[x]=min(mn[x<<1],mn[x<<1|1]);
    }
    
    inline void pushdown(int x,int ln,int rn){
        lazy[x<<1]+=lazy[x];
        sum[x<<1]+=(LL)ln*lazy[x];
        lazy[x<<1|1]+=lazy[x];
        sum[x<<1|1]+=(LL)rn*lazy[x];
        mn[x<<1]+=lazy[x];mn[x<<1|1]+=lazy[x];
        lazy[x]=0;
    }
    
    inline void update(int x,int l,int r,int L,int R,int k){
        if(L<=l && r<=R) {
            sum[x]-=k*(r-l+1);
            mn[x]-=k;lazy[x]-=k;
            if(mn[x]<0) flag=1;
            return ;
        }
        int mid=l+r>>1;
        if(lazy[x]) pushdown(x,mid-l+1,r-mid);
        if(mid>=L) update(x<<1,l,mid,L,R,k);
        if(mid<R) update(x<<1|1,mid+1,r,L,R,k);
        sum[x]=sum[x<<1]+sum[x<<1|1];
        mn[x]=min(mn[x<<1],mn[x<<1|1]);
    }
    
    int main(){
        n=rd(); m=rd();
        for(register int i=1;i<=n;i++) a[i]=rd();
        build(1,1,n);
        for(register int i=1;i<=m;i++){
            d[i]=rd(),s[i]=rd(),t[i]=rd();
            if(!flag) {
                update(1,1,n,s[i],t[i],d[i]);
                if(flag==1) ans=i;
            }
        }
        if(!flag) cout<<0<<endl;
        else{
            puts("-1");
            printf("%d",ans);
        }
        return 0;
    }

    二分+前缀和

    #include<bits/stdc++.h>
    
    using namespace std;
    const int MAXN = 1e6+6;
    
    int s[MAXN],t[MAXN],b[MAXN],a[MAXN],d[MAXN],sum[MAXN];
    int n,m,ans;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return x*f;
    }
    
    inline bool check(int x){
        memset(d,0,sizeof(d));
        for(register int i=1;i<=x;i++){
            d[s[i]]+=b[i];
            d[t[i]+1]-=b[i];        
        }
        for(register int i=1;i<=n;i++){
            sum[i]=sum[i-1]+d[i];
            if(sum[i]>a[i]) return false;
        }
        return true;
    }
    
    int main(){
        n=rd();m=rd();
        for(register int i=1;i<=n;i++) a[i]=rd();
        for(register int i=1;i<=m;i++) b[i]=rd(),s[i]=rd(),t[i]=rd();
        int l=1,r=m;
        while(l<=r) {
            int mid=l+r>>1;
            if(check(mid)) {
                ans=mid;
                l=mid+1;
            }else r=mid-1;
        }
        if(check(m)) cout<<0<<endl;
        else{
            cout<<-1<<endl;
            printf("%d",ans+1);
        } 
        return 0;
    }
  • 相关阅读:
    Interrupt、Interrupted、IsInterrupted
    ReentrantLock
    tcp粘包、拆包
    jstat 分析应用垃圾回收状况
    CopyOnWriteArrayList
    storm基础概念
    余弦距离
    websocket
    awk
    sed
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676906.html
Copyright © 2011-2022 走看看