SPOJ - GSS2Can you answer these queries II(线段树)
Posted Macaulish
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ - GSS2Can 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; }
以上是关于SPOJ - GSS2Can you answer these queries II(线段树)的主要内容,如果未能解决你的问题,请参考以下文章
SPOJ GSS2 Can you answer these queries II
Spoj GSS3 - Can you answer these queries III
SPOJ GSS3 Can you answer these queries III
SPOJ GSS4 Can you answer these queries IV