BZOJ4364:[IOI2014]Wall

浅谈区间最值操作与历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html

题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=4364

似乎可以不用吉司机线段树的作法……因为只需要维护区间最大最小值,也只有区间取最大最小值操作,所以可以直接用普通的线段树延迟标记解决这道问题。只要把最大值标记和最小值标记之间的关系处理得当即可。

时间复杂度:\(O((n+m)logn)\)

空间复杂度:\(O(n)\)

代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=2e6+6,inf=1e9;

int n,m;

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}

struct segmemt_tree {
    int mx[maxn<<2],mn[maxn<<2];
    int tagmx[maxn<<2],tagmn[maxn<<2];

    void update(int p) {
        mx[p]=max(mx[p<<1],mx[p<<1|1]);
        mn[p]=min(mn[p<<1],mn[p<<1|1]);
    }

    void build(int p,int l,int r) {
        tagmx[p]=-inf,tagmn[p]=inf;
        if(l==r)return;
        int mid=(l+r)>>1;
        build(p<<1,l,mid);
        build(p<<1|1,mid+1,r);
    }

    void Max_tag(int p,int v) {
        mx[p]=max(mx[p],v),mn[p]=max(mn[p],v);
        tagmx[p]=max(tagmx[p],v);tagmn[p]=max(tagmn[p],v);
    }

    void Min_tag(int p,int v) {
        mx[p]=min(mx[p],v),mn[p]=min(mn[p],v);
        tagmx[p]=min(tagmx[p],v),tagmn[p]=min(tagmn[p],v);
    }

    void push_down(int p) {
        if(tagmx[p]!=-inf) {
            Max_tag(p<<1,tagmx[p]);
            Max_tag(p<<1|1,tagmx[p]);
            tagmx[p]=-inf;
        }
        if(tagmn[p]!=inf) {
            Min_tag(p<<1,tagmn[p]);
            Min_tag(p<<1|1,tagmn[p]);
            tagmn[p]=inf;
        }
    }

    void Max(int p,int l,int r,int L,int R,int v) {
        if(L<=l&&r<=R) {
            Max_tag(p,v);
            return;
        }
        int mid=(l+r)>>1;push_down(p);
        if(L<=mid)Max(p<<1,l,mid,L,R,v);
        if(R>mid)Max(p<<1|1,mid+1,r,L,R,v);
        update(p);
    }

    void Min(int p,int l,int r,int L,int R,int v) {
        if(L<=l&&r<=R) {
            Min_tag(p,v);
            return;
        }
        int mid=(l+r)>>1;push_down(p);
        if(L<=mid)Min(p<<1,l,mid,L,R,v);
        if(R>mid)Min(p<<1|1,mid+1,r,L,R,v);
        update(p);
    }

    void print(int p,int l,int r) {
        if(l==r) {printf("%d\n",mx[p]);return;}
        int mid=(l+r)>>1;push_down(p);
        print(p<<1,l,mid),print(p<<1|1,mid+1,r);
    }
}T;

int main() {
    n=read(),m=read();T.build(1,1,n);
    for(int i=1;i<=m;i++) {
        int opt=read(),l=read()+1,r=read()+1,v=read();
        if(opt==1)T.Max(1,1,n,l,r,v);
        else T.Min(1,1,n,l,r,v);
    }T.print(1,1,n);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/AKMer/p/10227150.html