话说做过区间最大连续和,也做过区间去重求和,两个功能综合之后就郁闷了。一开始很单纯的想前后扫一遍,不过马上意识到思维差了太多了。看了网上的题解之后,豁然开朗,主要是利用累加记录最大值的思想。废话不多说了,思路到处有就不再赘述了。
ACcode:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using std::sort;
using std::unique;
typedef long long LL;
const int nsize=111111;
struct Line
{
int l,r;
int id;
Line() {}
Line(int a,int b,int c) :l(a),r(b),id(c) {}
bool operator < (const Line &cmp) const{
return r<cmp.r;
}
} line[nsize];
LL num[nsize];
LL add[nsize<<2],padd[nsize<<2];
LL sum[nsize<<2],pmax[nsize<<2];
int x[nsize],y[nsize],arr[nsize];
int Fin(int key,int len)
{
int m,l=0,r=len;
while (l<=r)
{
m=(l+r)>>1;
if (x[m]==key) return m;
else if (x[m]>key) r=m-1;
else l=m+1;
}
return -1;
}
LL Max(LL a1,LL a2)
{
return a1>a2?a1:a2;
}
void build(int rt,int l,int r)
{
sum[rt]=pmax[rt]=add[rt]=padd[rt]=0;
if (l==r) return ;
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
}
void PushUp(int rt)
{
int t1=rt<<1,t2=t1|1;
sum[rt]=Max(sum[t1],sum[t2]);
pmax[rt]=Max(pmax[t1],pmax[t2]);
}
void PushDown(int rt)
{
if (add[rt]||padd[rt])
{
int t1=rt<<1,t2=t1|1;
padd[t1]=Max(padd[t1],add[t1]+padd[rt]);
padd[t2]=Max(padd[t2],add[t2]+padd[rt]);
add[t1]+=add[rt]; add[t2]+=add[rt];
pmax[t1]=Max(pmax[t1],sum[t1]+padd[rt]);
pmax[t2]=Max(pmax[t2],sum[t2]+padd[rt]);
sum[t1]=sum[t1]+add[rt];
sum[t2]=sum[t2]+add[rt];
add[rt]=padd[rt]=0;
}
}
void update(int rt,int l,int r,int L,int R,int v)
{
if (L<=l&&r<=R)
{
sum[rt]+=v;
add[rt]+=v;
padd[rt]=Max(padd[rt],add[rt]);
pmax[rt]=Max(pmax[rt],sum[rt]);
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if (L<=m) update(rt<<1,l,m,L,R,v);
if (R>m) update(rt<<1|1,m+1,r,L,R,v);
PushUp(rt);
}
LL query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return pmax[rt];
PushDown(rt);
LL ans=0;
int m=(l+r)>>1;
if (L<=m) ans=Max(ans,query(rt<<1,l,m,L,R));
if (R>m) ans=Max(ans,query(rt<<1|1,m+1,r,L,R));
return ans;
}
int main()
{
int i,j,k,n,q,a,b;
int top,pos;
while (~scanf("%d",&n))
{
for (top=0,i=1; i<=n; i++)
scanf("%d",arr+i),x[top++]=arr[i];
scanf("%d",&q);
for (i=0; i<q; i++)
{
scanf("%d %d",&a,&b);
if (a>b) k=a,a=b,b=k;
line[i]=Line(a,b,i);
}
sort(x,x+top);
sort(line,line+q);
top=unique(x,x+top)-x-1;
build(1,1,n);
memset(y,0,sizeof(y));
for (i=0,j=1; i<q; i++)
{
a=line[i].l, b=line[i].r;
while (j<=b)
{
k=Fin(arr[j],top);
update(1,1,n,y[k]+1,j,arr[j]);
y[k]=j++;
}
LL t=query(1,1,n,a,b);
num[line[i].id]=Max(t,0);
}
for (i=0; i<q; i++) printf("%lld\n",num[i]);
puts("");
}
return 0;
}