• 洛谷 1083 (NOIp2012) 借教室——标记永久化线段树 / 差分+二分


    题目:https://www.luogu.org/problemnew/show/P1083

    听说线段树不标记永久化会T一个点。

    注意mn记录的是本层以下、带上标记的min!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e6+5,INF=1e9+5;
    int n,m,a[N],L,R,w,tot,ls[N<<1],rs[N<<1],mn[N<<1],laz[N<<1];
    bool flag;
    int rdn()
    {
        int ret=0;char ch=getchar();
        while(ch>'9'||ch<'0')ch=getchar();
        while(ch>='0'&&ch<='9')(ret*=10)+=ch-'0',ch=getchar();
        return ret;
    }
    void pshp(int cr)
    {
        mn[cr]=min(mn[ls[cr]],mn[rs[cr]])-laz[cr];//-laz[cr]!!
    }
    void build(int l,int r,int cr)
    {
        mn[cr]=INF;
        if(l==r){mn[cr]=a[l];return;}
        int mid=l+r>>1;
        ls[cr]=++tot;build(l,mid,ls[cr]);
        rs[cr]=++tot;build(mid+1,r,rs[cr]);
        pshp(cr);
    }
    void mdfy(int l,int r,int cr,int lj)
    {
        if(l>=L&&r<=R)
            {laz[cr]+=w;mn[cr]-=w;return;}
        int mid=l+r>>1;
        if(L<=mid)mdfy(l,mid,ls[cr],lj+laz[cr]);
        if(mid<R)mdfy(mid+1,r,rs[cr],lj+laz[cr]);
        pshp(cr);
    }
    int main()
    {
        n=rdn();m=rdn();
        for(int i=1;i<=n;i++)a[i]=rdn();
        tot=1;build(1,n,1);int i;
        for(i=1;i<=m;i++)
        {
            w=rdn();L=rdn();R=rdn();
            mdfy(1,n,1,0);
            if(mn[1]<0)break;
        }
        if(i==m+1)printf("0
    ");
        else printf("-1
    %d
    ",i);
        return 0;
    }
    View Code

    然而用每次遍历一下整个数组的二分答案也能做到nlogn。

    注意不要把c[ ]弄成真的差分,再弄一个yc[ ]每次memcpy,不然比线段树还慢。如果把减弄成加,每次memset成0,就能快很多。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=1e6+5;
    int n,m,a[N],c[N],l[N],r[N],d[N];
    bool pan(int k)
    {
        memset(c,0,sizeof c);
        for(int i=1;i<=k;i++)c[l[i]]+=d[i],c[r[i]+1]-=d[i];
        for(int i=1,sum=0;i<=n;i++)
        {
            sum+=c[i];
            if(sum>a[i])return true;
        }
        return false;
    }
    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],&l[i],&r[i]);
        int l=1,r=m,ans=0;
        while(l<=r)
        {
            int mid=l+r>>1;
            if(pan(mid))ans=mid,r=mid-1;
            else l=mid+1;
        }
        if(!ans)printf("0
    ");
        else printf("-1
    %d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Eclipse关于怎么调出web project
    RMI(远程方法调用)入门
    XSS攻击
    微信小程序
    java——IO流01
    06 python下
    06python上
    05python下
    05python上
    Nginx & Apache_网站用户认证
  • 原文地址:https://www.cnblogs.com/Narh/p/9419822.html
Copyright © 2020-2023  润新知