现在的位置: 首页 > 综合 > 正文

UESTC 1425

2013年06月19日 ⁄ 综合 ⁄ 共 2196字 ⁄ 字号 评论关闭

题目

和hdu 3308差不多

多了pushudown来更新区间内的值

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 100005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct Tree{
    int l,r;
    int lazy;
    int lsum,rsum,msum;//分别为左儿子最长子序列,右儿子最长子序列,最优子序列
    int lnum,rnum;//最左值,最右值
}tree[maxn<<2];

int num[maxn];

void PushUp(int rt)
{
    int l,r,m;
    l=tree[rt].l;
    r=tree[rt].r;
    m=(l+r)>>1;
    tree[rt].lnum=tree[rt<<1].lnum;
    tree[rt].rnum=tree[rt<<1|1].rnum;
    tree[rt].lsum=tree[rt<<1].lsum;
    tree[rt].rsum=tree[rt<<1|1].rsum;
    tree[rt].msum=max(tree[rt<<1].msum,tree[rt<<1|1].msum);
    if(tree[rt<<1].rnum<tree[rt<<1|1].lnum){
        if(tree[rt<<1].lsum==m-l+1)
            tree[rt].lsum+=tree[rt<<1|1].lsum;
        if(tree[rt<<1|1].rsum==r-m)
            tree[rt].rsum+=tree[rt<<1].rsum;
        tree[rt].msum=max(tree[rt].msum,tree[rt<<1].rsum+tree[rt<<1|1].lsum);
    }
}

void PushDown(int rt)
{
    if(tree[rt].lazy){
        tree[rt<<1].lazy+=tree[rt].lazy;
        tree[rt<<1].lnum+=tree[rt].lazy;
        tree[rt<<1].rnum+=tree[rt].lazy;
        tree[rt<<1|1].lazy+=tree[rt].lazy;
        tree[rt<<1|1].lnum+=tree[rt].lazy;
        tree[rt<<1|1].rnum+=tree[rt].lazy;
        tree[rt].lazy=0;
    }
}

void build(int l,int r ,int rt)
{
    tree[rt].l=l;
    tree[rt].r=r;
    tree[rt].lazy=0;
    if(l==r){
        tree[rt].rnum=tree[rt].lnum=num[l];
        tree[rt].msum=tree[rt].lsum=tree[rt].rsum=1;
        return ;
    }

    int m=(l+r)>>1;
    build(lson);
    build(rson);
    PushUp(rt);
}

void update(int x,int y,int val,int rt){
    int l,r;
    l=tree[rt].l;
    r=tree[rt].r;
    if(x==l&&r==y){
        tree[rt].lazy+=val;
        tree[rt].lnum+=val;
        tree[rt].rnum+=val;
        return ;
    }
    PushDown(rt);
    int m=(l+r)>>1;
    if(x<=m) update(x,min(m,y),val,rt<<1);
    if(y>m) update(max(m+1,x),y,val,rt<<1|1);
    PushUp(rt);
}

int query(int x,int y,int rt)
{
    int l,r;
    l=tree[rt].l;
    r=tree[rt].r;
    if(l==x&&r==y){
        return tree[rt].msum;
    }
  //  PushDown(rt);
    int m=(l+r)>>1;
    int ans=0;
    if(x<=m) ans=max(ans,query(x,min(m,y),rt<<1));
    if(y>m) ans=max(ans,query(max(m+1,x),y,rt<<1|1));
    if(tree[rt<<1].rnum<tree[rt<<1|1].lnum){
        ans=max(ans,min(tree[rt<<1].rsum,m-x+1)+min(tree[rt<<1|1].lsum,y-m));
    }
    return ans;
}

int main()
{
//    freopen("1.txt","r",stdin);
    int T,n,m,ncase=1;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&num[i]);
        build(1,n,1);
        printf("Case #%d:\n",ncase++);
        while(m--){
            int a,b,c;
            char s[10];
            scanf("%s",s);
            if(s[0]=='q'){
                scanf("%d%d",&a,&b);
                printf("%d\n",query(a,b,1));
            }
            else{
                scanf("%d%d%d",&a,&b,&c);
                update(a,b,c,1);
            }
        }
    }
    return 0;
}

抱歉!评论已关闭.