• 洛谷 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;
    }
  • 相关阅读:
    pytorch bug: for step,data in enumerate(loader)+Connection reset by peer
    pytorch bug
    ImportError: No module named '_tkinter', please install the python3-tk package
    nvidia-docker+cuda8.0+ubuntu16.04
    召回率,精确率,mAP如何计算
    tensorflow 迭代周期长,每个epoch时间变慢
    yolov3中 预测的bbox如何从特征图映射到原图?
    知乎问题:目标检测领域还有什么可以做的?
    目标检测数据增强,旋转方法
    OpenBLAS(1)----安装OpenBLAS
  • 原文地址:https://www.cnblogs.com/Narh/p/9419822.html
Copyright © 2020-2023  润新知