您的位置:首页 > 产品设计 > UI/UE

bzoj 2482: [Spoj1557] Can you answer these queries II

2015-06-16 20:27 543 查看

Description

给定n个元素的序列。

给出m个询问:求l[i]~r[i]的最大子段和(可选空子段)。

这个最大子段和有点特殊:一个数字在一段中出现了两次只算一次。

比如:1,2,3,2,2,2出现了3次,但只算一次,于是这个序列的和是1+2+3=6。

Input

第一行一个数n。

第二行n个数,为给定的序列,这些数的绝对值小于等于100000。

第三行一个数m。

接下来m行,每行两个数,l[i],r[i]。

Output

M行,每行一个数,为每个询问的答案。





Sample Input

9

4 -2 -2 3 -1 -4 2 2 -6

3

1 2

1 5

4 9

Sample Output

4

5

3

HINT

【数据说明】

30%:1 <= n, m <= 100

100%:1 <= n, m <= 100000

Source

spoj gss2

枚举右端点。我们用线段树维护以这个点开始到当前点的ans和过去最大ans
然后离线回答询问即可
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
struct tree
{
int l,r;
long long m,vm;
long long tag,vtag;
}tr[800001];
struct que
{
int l,r;
int p;
long long ans;
}ask[100001];
inline bool cmp1(que x,que y)
{
if(x.r<y.r)
return true;
return false;
}
inline bool cmp2(que x,que y)
{
if(x.p<y.p)
return true;
return false;
}
inline void up(int p)
{
tr[p].m=max(tr[p*2].m,tr[p*2+1].m);
tr[p].vm=max(tr[p*2].vm,tr[p*2+1].vm);
}
inline void push(int p)
{
tr[p*2].vm=max(tr[p*2].vm,tr[p*2].m+tr[p].vtag);
tr[p*2+1].vm=max(tr[p*2+1].vm,tr[p*2+1].m+tr[p].vtag);
tr[p*2].m+=tr[p].tag;
tr[p*2+1].m+=tr[p].tag;

tr[p*2].vtag=max(tr[p*2].vtag,tr[p*2].tag+tr[p].vtag);
tr[p*2+1].vtag=max(tr[p*2+1].vtag,tr[p*2+1].tag+tr[p].vtag);
tr[p*2].tag+=tr[p].tag;
tr[p*2+1].tag+=tr[p].tag;
tr[p].tag=0;
tr[p].vtag=0;
}
inline void build(int p,int l,int r)
{
tr[p].l=l;
tr[p].r=r;
if(l!=r)
{
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
up(p);
}
}
inline void add(int p,int l,int r,long long x)
{
if(l>r)
return ;
/* if(l==0)
l=1;*/
if(l<=tr[p].l&&tr[p].r<=r)
{
tr[p].m+=x;
tr[p].tag+=x;
tr[p].vm=max(tr[p].vm,tr[p].m);
tr[p].vtag=max(tr[p].vtag,tr[p].tag);
}
else
{
push(p);
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
add(p*2,l,r,x);
if(r>mid)
add(p*2+1,l,r,x);
up(p);
}
}
inline long long askx(int p,int l,int r)
{
if(l<=tr[p].l&&tr[p].r<=r)
return tr[p].vm;
else
{
push(p);
int mid=(tr[p].l+tr[p].r)/2;
long long ans=0;
if(l<=mid)
ans=max(ans,askx(p*2,l,r));
if(r>mid)
ans=max(ans,askx(p*2+1,l,r));
return ans;
}
}
int a[1000001];
int pre[1000001],la[1000001];
int main()
{
//	 freopen("sequence.in","r",stdin);
//	 freopen("sequence.out","w",stdout);
int n;
scanf("%d",&n);
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
pre[i]=la[a[i]];
la[a[i]]=i;
}
build(1,1,n);
int m;
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&ask[i].l,&ask[i].r);
ask[i].p=i;
}
sort(ask+1,ask+1+m,cmp1);
int d=1;
for(i=1;i<=n;i++)
{
add(1,pre[i]+1,i,a[i]);
while(d<=m&&ask[d].r==i)
{
ask[d].ans=askx(1,ask[d].l,ask[d].r);
d++;
}
}
sort(ask+1,ask+1+m,cmp2);
for(i=1;i<=m;i++)
printf("%lld\n",ask[i].ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: