HLG 1524 最大

题意: 给一列数对应两种操作:

         1 a b v, 把[a, b] 的值改为v,即A[a] = A[a+1] = ... = A[b] = v

         2 a b, 查询[a, b] 之间的相同数的连续和最大值。
分析:线段树,区间合并 + 成段更新 ... 
        int lva[maxn<<4];    // 区间最左面的值
        int lnu[maxn<<4];   // 区间最左面的数的个数
        int rva[maxn<<4];   // 区间最右面的值
        int rnu[maxn<<4];  // 区间最右面的数的个数
        int mva[maxn<<4]; // 区间最大连续值
        int add[maxn<<4];  // 延迟标记
        区间合并:
        当左儿子区间相同数字的长度达到区间长度且lva[lson]==lva[rson]时, 将左儿子和右儿子的 lnu合并
        当右儿子区间相同数字的长度达到区间长度且rva[rson]==rva[lson]时,将左儿子和右儿子的 rnu合并
PS: 由于延迟标记 add[i] 在开始时默认add[i]为正值的时候才进行延迟覆盖, 而题目中 更新的 V 值可以为 0,这就意味着add[i]=0 的时候也要进行延迟更新,
        为此debug了两个点,谨记...延迟标记要默认为达不到的值,这题只要默认为 -1 即可。
#include<stdio.h>
#include<string.h>
#define clr(x)memset(x,0,sizeof(x))
#define maxn 100005
int max(int a,int b)
{ return a>b?a:b;}
int min(int a,int b)
{ return a<b?a:b;}
int lva[maxn<<4]; // 最左面的值
int lnu[maxn<<4]; // 最左面的数的个数
int rva[maxn<<4]; // 最右面的值
int rnu[maxn<<4]; // 最右面的数的个数
int mva[maxn<<4]; // 区间最大连续值
int add[maxn<<4]; // 延迟标记
int v[maxn];
void creat(int l,int r,int rt)
{
    add[rt]=-1;
    if(l==r)
    {
        lva[rt]=rva[rt]=v[l];
        lnu[rt]=rnu[rt]=1;
        mva[rt]=v[l];
        return;
    }
    int m=(l+r)>>1;
    creat(l,m,rt<<1);
    creat(m+1,r,rt<<1|1);
    lva[rt]=lva[rt<<1];
    lnu[rt]=lnu[rt<<1];
    rva[rt]=rva[rt<<1|1];
    rnu[rt]=rnu[rt<<1|1];
    if(lva[rt<<1]==lva[rt<<1|1]&&lnu[rt<<1]==(m-l+1))
        lnu[rt]+=lnu[rt<<1|1];
    if(rva[rt<<1]==rva[rt<<1|1]&&rnu[rt<<1|1]==r-m)
        rnu[rt]+=rnu[rt<<1];
    mva[rt]=max(mva[rt<<1],mva[rt<<1|1]);
    if(rva[rt<<1]==lva[rt<<1|1])
        mva[rt]=max(mva[rt],rva[rt<<1]*rnu[rt<<1]+lva[rt<<1|1]*lnu[rt<<1|1]);
}
void update(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&r<=R)
    {
        add[rt]=c;
        lva[rt]=rva[rt]=c;
        lnu[rt]=rnu[rt]=r-l+1;
        mva[rt]=c*(r-l+1);
        return;
    }
    int m=(l+r)>>1;
    if(add[rt]!=-1)
    {
        add[rt<<1]=add[rt<<1|1]=add[rt];
        lva[rt<<1]=rva[rt<<1]=lva[rt<<1|1]=rva[rt<<1|1]=add[rt];
        lnu[rt<<1]=rnu[rt<<1]=m-l+1;
        lnu[rt<<1|1]=rnu[rt<<1|1]=r-m;
        mva[rt<<1]=(m-l+1)*add[rt];
        mva[rt<<1|1]=(r-m)*add[rt];
        add[rt]=-1;
    }
    if(L<=m)
        update(L,R,c,l,m,rt<<1);
    if(R>m)
        update(L,R,c,m+1,r,rt<<1|1);
    lva[rt]=lva[rt<<1];
    lnu[rt]=lnu[rt<<1];
    rva[rt]=rva[rt<<1|1];
    rnu[rt]=rnu[rt<<1|1];
    if(lva[rt<<1]==lva[rt<<1|1]&&lnu[rt<<1]==(m-l+1))
        lnu[rt]+=lnu[rt<<1|1];
    if(rva[rt<<1]==rva[rt<<1|1]&&rnu[rt<<1|1]==r-m)
        rnu[rt]+=rnu[rt<<1];
    mva[rt]=max(mva[rt<<1],mva[rt<<1|1]);
    if(rva[rt<<1]==lva[rt<<1|1])
        mva[rt]=max(mva[rt],rva[rt<<1]*rnu[rt<<1]+lva[rt<<1|1]*lnu[rt<<1|1]);
}
int query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
        return mva[rt];
    int m=(l+r)>>1;
    if(add[rt]!=-1)
    {
        add[rt<<1]=add[rt<<1|1]=add[rt];
        lva[rt<<1]=rva[rt<<1]=lva[rt<<1|1]=rva[rt<<1|1]=add[rt];
        lnu[rt<<1]=rnu[rt<<1]=m-l+1;
        lnu[rt<<1|1]=rnu[rt<<1|1]=r-m;
        mva[rt<<1]=(m-l+1)*add[rt];
        mva[rt<<1|1]=(r-m)*add[rt];
        add[rt]=-1;
    }
    if(R<=m)
        return query(L,R,l,m,rt<<1);
    else if(L>m)
        return query(L,R,m+1,r,rt<<1|1);
    else 
    {
        int    res=0;
        if(rva[rt<<1]==lva[rt<<1|1])
            res=(min(rnu[rt<<1],m-L+1)+min(lnu[rt<<1|1],R-m))*rva[rt<<1];
        return max(res,max(query(L,m,l,m,rt<<1),query(m+1,R,m+1,r,rt<<1|1)));
    }
}
int re[100005];
int main()
{
    int i,n,a,b,c,m,op,ca=1,top=0;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&v[i]);
        creat(1,n,1);
        scanf("%d",&m);
        int tot=0;
        printf("Case %d:\n",ca++);
        while(m--)
        {
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d%d%d",&a,&b,&c);
                update(a,b,c,1,n,1);
            }
            else
            {
                scanf("%d%d",&a,&b);
                printf("%d\n",query(a,b,1,n,1));
            }
        }
    }
    return 0;
}

 

posted @ 2012-08-10 11:49  'wind  阅读(240)  评论(0编辑  收藏  举报