Topic link: https://www.spoj.com/problems/GSS2/en/
To give you an array of length n, there are q queries. Each query gives an interval [X,Y]. You are asked to find MAX:{sum [i, j]} (X<=i<=j<=Y). At the same time, when the interval summation occurs, if a number occurs many times, then the sum is calculated only once.
Topic idea: Usually we use line segment tree to solve the problem of finding the maximum subsection and interval, but this problem needs to solve the problem of number repetition.
To solve this problem, an off-line operation can be carried out, using a vis[a[i] (a[i] may be negative, so remember to add 100000) array to store the location of the last occurrence of a[i] number, and then use only the interval of [vis[a[i], i] plus a[i] for each update and sum.
Then the queries are sorted according to the right endpoint of the interval, which is updated and solved at the same time.
Four values are stored in the segment tree
MAX: Storing the Optimal Solution of the Current Interval
sum: Stores the maximum of the current interval
lazy: lazy flag used to record downloaded values
prelazy: The second lazy flag that records the maximum download value
Why do we use two lazy markers here? The first one is for normal interval update operation, while the second one is for updating the optimal solution, such as - 5 in an interval, but there is a lazy marker 5 in his left son. For his left son, adding 5 directly is the optimal solution.
Specific implementation depends on the code:
#include <bits/stdc++.h> #define fi first #define se second #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pb push_back #define MP make_pair #define debug(x) cout<<"["<<x<<"]"<<endl #define FIN freopen("in.txt","r",stdin) using namespace std; typedef long long LL; typedef pair<int,int>pii; const int M=1e5; const int MX=2e5+7; int n,m; int a[MX]; int MAX[MX<<2],lazy[MX<<2],prelazy[MX<<2],sum[MX<<2]; int vis[MX]; struct que{ int l,r,id; LL ans; bool operator<(const que &que1)const{ return r<que1.r; } }q[MX]; void push_up(int rt){ MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]); sum[rt]=max(sum[rt<<1],sum[rt<<1|1]); } void push_down(int rt){ if(lazy[rt] || prelazy[rt]){ prelazy[rt<<1]=max(prelazy[rt<<1],prelazy[rt]+lazy[rt<<1]); MAX[rt<<1]=max(MAX[rt<<1],sum[rt<<1]+prelazy[rt]); lazy[rt<<1]+=lazy[rt];sum[rt<<1]+=lazy[rt]; prelazy[rt<<1|1]=max(prelazy[rt<<1|1],prelazy[rt]+lazy[rt<<1|1]); MAX[rt<<1|1]=max(MAX[rt<<1|1],sum[rt<<1|1]+prelazy[rt]); lazy[rt<<1|1]+=lazy[rt];sum[rt<<1|1]+=lazy[rt]; lazy[rt]=prelazy[rt]=0; } } void build(int l,int r,int rt){ MAX[rt]=lazy[rt]=prelazy[rt]=sum[rt]=0; if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); push_up(rt); } void update(int L,int R,LL x,int l,int r,int rt){ if(L<=l&&r<=R){ sum[rt]+=x;lazy[rt]+=x; prelazy[rt]=max(prelazy[rt],lazy[rt]); MAX[rt]=max(MAX[rt],sum[rt]); return; } push_down(rt); int m=(l+r)>>1; if(L<=m) update(L,R,x,lson); if(R>m) update(L,R,x,rson); push_up(rt); } LL query(int L,int R,int l,int r,int rt){ if(L<=l && r<=R) return MAX[rt]; push_down(rt); int m=(l+r)>>1; LL res=0; if(L<=m) res=max(res,query(L,R,lson)); if(R>m) res=max(res,query(L,R,rson)); return res; } int main(){ while(~scanf("%d",&n)){ memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,n,1); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d%d",&q[i].l,&q[i].r); q[i].id=i; } sort(q+1,q+m+1); int j=1; for(int i=1;i<=n;i++){ update(vis[a[i]+M]+1,i,a[i],1,n,1); vis[a[i]+M]=i; while(j<=m && q[j].r==i){ q[q[j].id].ans=query(q[j].l,q[j].r,1,n,1); j++; } } for(int i=1;i<=m;i++) printf("%lld\n", q[i].ans); } return 0; }