BZOJ 4355 : Play with sequence(对于某一个特定的区间进行取 max 操作 或者取 min 操作)

4355: Play with sequence

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 300  Solved: 91
[Submit][Status][Discuss]

Description

维护一个长度为N的序列a,现在有三种操作:

1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a[V]都赋值为C。

2)给出参数U,V,C,对于区间[U,V]里的每个数i,将a[i]赋值为max(a[i]+C,0)。

3)给出参数U,V,输出a[U],a[U+1],...,a[V-1],a[V]里值为0的数字个数。

Input

第一行包含两个正整数N,M(1<=N,M<=300000),分别表示序列长度和操作个数。

第二行包含N个整数,其中第i个数表示a[i](0<=a[i]<=10^9),描述序列的初始状态。

接下来M行描述M个操作,保证1<=U<=V<=N,对于操作1,0<=C<=10^9,对于操作2,|C|<=10^9。

Output

输出若干行,每行一个整数,依次回答每个操作3的问题。

Sample Input

5 3
6 4 6 6 4
2 1 5 -5
1 3 4 4
3 1 5

Sample Output

2

HINT

2016.1.1新加数据

Source

鸣谢Claris

[Submit][Status][Discuss]

推荐一篇博客。

大佬的博客!!!点点点!!!

类似题: hdu 5306

代码: 

#include<bits/stdc++.h>
#define lson (i<<1)
#define rson (i<<1|1)

using namespace std;
typedef long long ll;
const ll inf =1e17+5;
const int N =3e5+5;
ll a[N];

struct node
{
    ll mn,cmn;
    ll cnt;
    ll lz;
    ll cov;
    ll add;
    int l,r;
}tr[N<<2];

void solve(int i,ll cov)
{
    int l,r;  l=tr[i].l;  r=tr[i].r;
    tr[i].mn=cov;
    tr[i].cnt=r-l+1;
    tr[i].cmn=inf;
    tr[i].lz=-inf;
    tr[i].add=0;
    tr[i].cov=cov;
    return ;
}

void solve1(int i,ll add)
{
    int l,r; l=tr[i].l; r=tr[i].r;
    tr[i].mn+=add;
    if(tr[i].cmn!=inf) tr[i].cmn+=add;
    if(tr[i].lz!=-inf ) tr[i].lz+=add;
    if(tr[i].cov!=inf ) tr[i].cov+=add;
    else tr[i].add+=add;
}

void solve2(int i,ll lz)
{
    if(lz>tr[i].mn){  //如果当前的lz大于当前的最小值
            //那么要更新当前的最小值为lz 因为是push_down
        tr[i].lz=lz;
        tr[i].mn=lz;
    }
}

void push_up(int i)
{
    tr[i].mn=min(tr[lson].mn,tr[rson].mn);
    if(tr[lson].mn==tr[rson].mn){
        tr[i].cnt=tr[lson].cnt+tr[rson].cnt;
        tr[i].cmn=min(tr[lson].cmn,tr[rson].cmn);
    }
    else if(tr[lson].mn<tr[rson].mn){  // 左孩子的最小值小
        tr[i].cnt=tr[lson].cnt;
        tr[i].cmn=min(tr[lson].cmn,tr[rson].mn);
    }
    else{  // 右孩子的最小值最小
        tr[i].cnt=tr[rson].cnt;
        tr[i].cmn=min(tr[lson].mn,tr[rson].cmn);
    }
}

void push_down(int i)
{
    if(tr[i].add!=0){
        solve1(lson,tr[i].add);
        solve1(rson,tr[i].add);
        tr[i].add=0;
    }
    if(tr[i].cov!=inf){
        solve(lson,tr[i].cov);
        solve(rson,tr[i].cov);
        tr[i].cov=inf;
    }
    if(tr[i].lz!=-inf){
        solve2(lson,tr[i].lz);
        solve2(rson,tr[i].lz);
        tr[i].lz=-inf;
    }
    return ;
}

void build(int i,int l,int r)
{
    tr[i].l=l; tr[i].r=r; tr[i].add=0; tr[i].cmn=inf;
    tr[i].lz=-inf; tr[i].cov=inf; tr[i].cnt=0; tr[i].mn=inf;
    if(l==r){
        tr[i].mn=a[l]; tr[i].cnt=1;
        return ;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    push_up(i);
}

void add(int i,int l,int r,ll val)
{
    //cout<<"i "<<" l "<<tr[i].l<<" r "<<tr[i].r<<" ll "<<l<<" rr "<<r<<endl;
    if(tr[i].l==l&&tr[i].r==r){
        solve1(i,val);
        return ;
    }
    int mid=(tr[i].l+tr[i].r)>>1;
    push_down(i);
    if(r<=mid) add(lson,l,r,val);
    else if(l>mid) add(rson,l,r,val);
    else{
        add(lson,l,mid,val);
        add(rson,mid+1,r,val);
    }
    push_up(i);
    return ;
}

void cover(int i,int l,int r,ll val)
{
    if(tr[i].l==l&&tr[i].r==r){
        solve(i,val);
        return ;
    }
    int mid=(tr[i].l+tr[i].r)>>1;
    push_down(i);
    if(r<=mid) cover(lson,l,r,val);
    else if(l>mid) cover(rson,l,r,val);
    else{
        cover(lson,l,mid,val);
        cover(rson,mid+1,r,val);
    }
    push_up(i);
}

void upmax(int i,int l,int r,ll val)
{
    if(tr[i].l==l&&tr[i].r==r){
        if(tr[i].mn>=val) return ;
        if(tr[i].cmn>val){
            tr[i].mn=val;
            tr[i].lz=val;
            return ;
        }
    }
    int mid=(tr[i].l+tr[i].r)>>1;
    push_down(i);
    if(r<=mid) upmax(lson,l,r,val);
    else if(l>mid) upmax(rson,l,r,val);
    else{
        upmax(lson,l,mid,val);
        upmax(rson,mid+1,r,val);
    }
    push_up(i);
}

ll ans;

void query(int i,int l,int r)
{
    if(tr[i].l==l&&tr[i].r==r){
        if(tr[i].mn==0) ans+=tr[i].cnt;
        return ;
    }
    int mid=(tr[i].l+tr[i].r)>>1;
    push_down(i);
    if(r<=mid) query(lson,l,r);
    else if(l>mid) query(rson,l,r);
    else{
        query(lson,l,mid);
        query(rson,mid+1,r);
    }
    push_up(i);
}

int n,m;

int main()
{
    int op,l,r;
    ll val;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    build(1,1,n);
    while(m--)
    {
        scanf("%d %d %d",&op,&l,&r);
        if(op==1){
            scanf("%lld",&val);
            cover(1,l,r,val);
        }
        else if(op==2){
            scanf("%lld",&val);
            //cout<<"*** "<<endl;
            add(1,l,r,val);
            //cout<<"*******"<<endl;
            upmax(1,l,r,0);
        }
        else{
            ans=0;
            query(1,l,r);
            printf("%lld\n",ans);
        }
    }
    return 0;
}



猜你喜欢

转载自blog.csdn.net/yjt9299/article/details/81270667
今日推荐