HDU 5306 Gorgeous Sequence

http://acm.hdu.edu.cn/showproblem.php?pid=5306

题意:
1.区间 [l,r] 对 x 取 min
2.区间查询最大值
3.区间查询和

分析:

线段树区间更新查找,查找比较容易,就是按照模板,更新需要进行查找需要更新的点,进行标记,然后通过需要更新点的个数来求和

代码:

#include<bits/stdc++.h>
using namespace std;
long long  a[1000010];
#define mod 1000000007
long long Sum,Maxn;
struct node
{
    long long  lazy,cnt,maxn,l,r;
    long long sum;
}v[1000010<<2];
void update(int k,long long  val)
{
    if(v[k].lazy!=0&&v[k].lazy<=val)return;
    v[k].lazy=val;
    
    if(v[k].cnt!=v[k].r-v[k].l+1)
    {
        v[k].maxn=val;
        v[k].sum+=(v[k].r-v[k].l+1-v[k].cnt)*val;
        v[k].cnt=v[k].r-v[k].l+1;
        
    }
}
void pushUp(int k)
{
    v[k].maxn=max(v[k<<1].maxn,v[(k<<1)+1].maxn);
    v[k].sum=v[k<<1].sum+v[(k<<1)+1].sum;
    v[k].cnt=v[k<<1].cnt+v[(k<<1)+1].cnt;
}
void dfs(int k,long long val)
{
    if(v[k].maxn<=val)return;
    
    v[k].lazy=0;
    if(v[k].l==v[k].r)
    {
        v[k].cnt=v[k].maxn=v[k].sum=0;
        
        return;
    }
    dfs(k<<1,val);
    dfs((k<<1)+1,val);
    pushUp(k);
}
void pushDown(int k)
{
     if(v[k].lazy==0)return;
     update(k<<1,v[k].lazy);
     update((k<<1)+1,v[k].lazy);
     v[k].lazy=0;
}
void build(int k,long long l,long long r)
{
    v[k].l=l;
    v[k].r=r;
    v[k].lazy=0;
    if(l==r)
    {
        v[k].sum=v[k].maxn=v[k].lazy=a[l];
        v[k].cnt=1;
        return;
    }
    long long mid;
    mid=(l+r)>>1;
    build(k<<1,l,mid);
    build((k<<1)+1,mid+1,r);
    pushUp(k);
}

void gai(int k,long long ll,long long rr,long long val)
{
    if(v[k].maxn<=val)return;
    if(v[k].l>=ll&&v[k].r<=rr)
    {
        dfs(k,val);
        update(k,val);
        return;
    }
    pushDown(k);
    long long mid;
    mid=(v[k].l+v[k].r)>>1;
    if(mid>=ll)
        gai(k<<1,ll,rr,val);
    if(mid<rr)
        gai((k<<1)+1,ll,rr,val);
    pushUp(k);

}
void get(int k,long long ll,long long rr)
{
    if(v[k].l>=ll&&v[k].r<=rr)
    {
        Sum+=v[k].sum;
        Maxn=max(Maxn,v[k].maxn);
        return;
    }
    long long mid;
    mid=(v[k].l+v[k].r)>>1;
    pushDown(k);
    if(mid>=ll)
        get(k<<1,ll,rr);
    if(mid<rr)
        get((k<<1)+1,ll,rr);
    pushUp(k);

}
int main()
{
    long long  t,i,j,n,m,x,aa,bb,cc;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&n,&m);
        for(i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        build(1,1,n);
        for(i=0;i<m;i++)
        {
            scanf("%lld",&x);
            if(x==0)
            {
                scanf("%lld%lld%lld",&aa,&bb,&cc);
                gai(1,aa,bb,cc);
            }
            else
            if(x==1)
            {
                scanf("%lld%lld",&aa,&bb);
                Maxn=0;
                get(1,aa,bb);
                printf("%lld\n",Maxn);
            }
            else
            {
                scanf("%lld%lld",&aa,&bb);
                Sum=0;
                get(1,aa,bb);
                printf("%lld\n",Sum);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lml11111/article/details/81088721