• Poj 3667


    这是第一题线段树的区间合并的题;

    这类的题用于求连续的最长长度什么的;

    这题我看的是一篇比较不错的博客;

    我把我的理解注释在代码里了;

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    const int maxn=55555;
    int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2]; //区间左端,右端,和整体的最大连续房间数目
    int cover[maxn<<2];
    void pushdown(int rt,int m) //更新儿子节点
    {
    if(cover[rt]!=-1)说明这个区间全空或者全满
    {
    cover[rt<<1]=cover[rt<<1|1]=cover[rt];
    msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=cover[rt]?0:m-(m>>1);
    msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=cover[rt]?0:m>>1;
    cover[rt]=-1;
    }
    }
    void pushup(int rt,int m) //更新根节点
    {
    lsum[rt]=lsum[rt<<1];
    rsum[rt]=rsum[rt<<1|1];
    if(lsum[rt]==m-(m>>1))
    lsum[rt]+=lsum[rt<<1|1];
    if(rsum[rt]==m>>1)
    rsum[rt]+=rsum[rt<<1];
    msum[rt]=max(lsum[rt<<1|1]+rsum[rt<<1],max(msum[rt<<1],msum[rt<<1|1]));
    }
    void build(int l,int r,int rt) //建立
    {
    msum[rt]=lsum[rt]=rsum[rt]=r-l+1;
    cover[rt]=-1;
    if(l==r)
    return ;
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    }
    void update(int L,int R,int c,int l,int r,int rt) 
    {
    if(L<=l&&r<=R)
    {
    msum[rt]=lsum[rt]=rsum[rt]=c?0:r-l+1;
    cover[rt]=c;
    return ;
    }
    pushdown(rt,r-l+1);
    int mid=(l+r)>>1;
    if(L<=mid)update(L,R,c,lson);
    if(R>mid)update(L,R,c,rson);
    pushup(rt,r-l+1);
    }
    int query(int w,int l,int r,int rt)//我觉得设计很巧妙,但是那种数据结构之美我不知道该怎么说。
    {
    if(l==r)return l;
    int mid=(l+r)>>1;
    pushdown(rt,r-l+1);
    if(msum[rt<<1]>=w)
    return query(w,lson);
    else
    {
    if(lsum[rt<<1|1]+rsum[rt<<1]>=w)
    return mid-rsum[rt<<1]+1;
    return query(w,rson);
    }
    }
    int main()
    {
    int n,m;
    scanf("%d%d",&n,&m);
    build(1,n,1);
    while(m--)
    {
    int op,a,b;
    scanf("%d",&op);
    if(op==1)
    {
    scanf("%d",&a);
    if(msum[1]<a)
    puts("0");
    else
    {
    int p=query(a,1,n,1);
    printf("%d ",p);
    update(p,p+a-1,1,1,n,1);
    }
    }
    else
    {
    scanf("%d%d",&a,&b);
    update(a,a+b-1,0,1,n,1);
    }
    }
    return 0;
    }

    这个代码是那个博客主写的,我觉得很漂亮,就复制过来了。

  • 相关阅读:
    消融实验(Ablation experiment)& 控制变量法
    reduce的方向
    深度学习和推荐系统的资料
    [Tailwind] Transitioning Rounded Corners using the JIT Compiler
    [JS Pattern] Proxy pattern
    git base cmd
    python app
    gitcmd ins tortoiseGitGUI
    vs vscode vs+ qt
    git branch tag
  • 原文地址:https://www.cnblogs.com/newadi/p/4064857.html
Copyright © 2020-2023  润新知