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

      正解是二分……

      emmm……

      我能说什么……

      鬼知道是二分啊!

      一开始想到的是线段树qwq

      于是乎——我就用线段树做的!

      我已开始一直在被一个问题困扰着,就是lazy标记的下传,觉得有点小麻烦,但是还是想出了下传的方法。可写着写着,突然发现似乎并不用下传,于是我就试了一下,竟然AC了!!!

      事后我才知道,这就是标记永久化的线段树……

      当前点的值=min(左儿子min-左儿子标记,右儿子min-右儿子标记)。

      当然最后查询根节点的min时也要减去根节点的标记。

      标记永久化的好处是速度会变快,以及便于删除标记。但是这道题没有删除操作。

      但是它也有它的局限性,它只支持每一次整体的询问,如果你要询问其中的某一段区间,标记永久化线段树可就要出锅啦……  

      接下来上代码:  

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define maxn 4*1000005
    struct node
    {
        int minn,lazy;
    } e[maxn];
    int l[maxn],r[maxn];
    void build(int L,int R,int now)
    {
        l[now]=L;
        r[now]=R;
        if(L==R)
        {
            scanf("%d",&e[now].minn);
            return ;
        } 
        int mid=(L+R)>>1;
        build(L,mid,now<<1);
        build(mid+1,R,now<<1|1);
        e[now].minn=min(e[now<<1].minn,e[now<<1|1].minn);
    }
    void forever(int now)
    {
        int ls=now<<1;
        int rs=now<<1|1;
        e[now].minn=min(e[ls].minn-e[ls].lazy,e[rs].minn-e[rs].lazy);
        return ;
    }
    void update(int L,int R,int k,int now)
    {
        if(L==l[now]&&R==r[now])
        {
            e[now].lazy+=k;
            return ;
        }
        int mid=(l[now]+r[now])>>1;
        if(R<=mid) update(L,R,k,now<<1); 
        else if(L>mid) update(L,R,k,now<<1|1);
        else 
        {
            update(L,mid,k,now<<1);
            update(mid+1,R,k,now<<1|1);
        }
        forever(now);
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        build(1,n,1);
        for(int i=1;i<=m;i++)
        {
            int l,r,k;
            scanf("%d%d%d",&k,&l,&r);
            update(l,r,k,1);
            if(e[1].minn-e[1].lazy<0)
            {
                printf("-1
    %d",i);
                return 0;
            }
        }
        printf("0");
        return 0;
    }
  • 相关阅读:
    MyISAM、InnoDB在频繁插入删除情况下的不同
    Solarized ----vim配色方案
    SVN命令使用详解
    好的网页
    snort在WinXP下的集成式安装
    matlab连接数据库
    KDD数据导入sqlserver2005数据库
    snort在使用过程中遇到的问题:抓不到包
    snort在使用过程中遇到的问题:ERROR: OpenAlertFile() => fopen() alert file log/alert.ids:No such file or directory
    将iso文件刻录为CD或DVD【转】
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/10354937.html
Copyright © 2011-2022 走看看