首页 > 代码库 > 【SPOJ - GSS2】Can you answer these queries II(线段树)

【SPOJ - GSS2】Can you answer these queries II(线段树)

区间连续不重复子段最大值,要维护历史的最大值和当前的最大值,打两个lazy,离线

 

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 150000
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define LL long long
using namespace std;

typedef struct {
    LL nmax,hmax,nlazy,hlazy;
}Tree;
Tree tree[maxn*10];

typedef struct {
    int l,r,id;
} Que;
Que que[maxn*2];

LL num[maxn*2],ans[maxn*2];
int n,m,pre[maxn*4];

int cmp(Que x,Que y)
{
    if (x.r<y.r) return 1;
    return 0;
}

void update(int x)
{
    tree[x].nmax=max(tree[x<<1].nmax,tree[x<<1|1].nmax);
    tree[x].hmax=max(tree[x<<1].hmax,tree[x<<1|1].hmax);
}

void pushdown(int x)
{
    if (tree[x].hlazy) {
        tree[x<<1].hmax=max(tree[x<<1].hmax,tree[x<<1].nmax+tree[x].hlazy);
        tree[x<<1|1].hmax=max(tree[x<<1|1].hmax,tree[x<<1|1].nmax+tree[x].hlazy);    
        tree[x<<1].hlazy=max(tree[x<<1].hlazy,tree[x].hlazy+tree[x<<1].nlazy);
        tree[x<<1|1].hlazy=max(tree[x<<1|1].hlazy,tree[x].hlazy+tree[x<<1|1].nlazy);
        tree[x].hlazy=0;
    }
    if (tree[x].nlazy) {
        tree[x<<1].nmax=tree[x<<1].nmax+tree[x].nlazy;
        tree[x<<1|1].nmax=tree[x<<1|1].nmax+tree[x].nlazy;
        tree[x<<1].nlazy+=tree[x].nlazy;
        tree[x<<1|1].nlazy+=tree[x].nlazy;
        tree[x].nlazy=0;
    }
}

void change(int x,int l,int r,int ll,int rr,LL y)
{
    if (ll<=l && r<=rr) {
        tree[x].nlazy+=y;
        tree[x].nmax+=y;
        tree[x].hlazy=max(tree[x].hlazy,tree[x].nlazy);
        tree[x].hmax=max(tree[x].nmax,tree[x].hmax);
        return;
    }
    pushdown(x);
    int mid=(l+r)>>1;
    if (ll<=mid) change(x<<1,l,mid,ll,rr,y);
    if (rr>mid) change(x<<1|1,mid+1,r,ll,rr,y);
    update(x);
}

LL ask(int x,int l,int r,int ll,int rr)
{
//    printf("%d %d %d %lld %lld\n",x,l,r,tree[x].hmax,tree[x].nmax);
    if (ll<=l && r<=rr) return tree[x].hmax;
    pushdown(x);
    int mid=(l+r)>>1;
    if (rr<=mid) return ask(x<<1,l,mid,ll,rr);
    else 
    if (ll>mid) return ask(x<<1|1,mid+1,r,ll,rr);
    else 
    return max(ask(x<<1,l,mid,ll,mid),ask(x<<1|1,mid+1,r,mid+1,rr));
}

void build(int x,int l,int r)
{
    tree[x].hlazy=tree[x].nlazy=0;
    if (l==r) {
        scanf("%lld",&num[l]);
        tree[x].hmax=tree[x].nmax=0;
        return;
    }
    int mid=(l+r)>>1;
    if (l<=mid) build(x<<1,l,mid);
    if (mid<r) build(x<<1|1,mid+1,r);
    update(x);
}

int main()
{
    scanf("%d",&n);
    build(1,1,n);
    scanf("%d",&m);
    rep(i,0,m-1) {
        scanf("%d %d",&que[i].l,&que[i].r);
        que[i].id=i;
    }
    sort(que,que+m,cmp);
    memset(pre,0,sizeof(pre));
    int now=0;
    rep(i,1,n) {
        change(1,1,n,pre[num[i]+maxn]+1,i,num[i]);
        pre[num[i]+maxn]=i;
        while (now<=m && que[now].r==i) {
            ans[que[now].id]=ask(1,1,n,que[now].l,que[now].r);
            ++now;
        }
    }
    rep(i,0,m-1) printf("%lld\n",ans[i]);
    return 0;
}
View Code

 

【SPOJ - GSS2】Can you answer these queries II(线段树)