转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove
题目:求出区间的最大子段和,而且相同的数只能计算一次
http://www.spoj.pl/problems/GSS2/
嘛~~~这个题还是很不错的,不会,哭~~~~喵
在线的处理不了,只能离线处理
按询问区间的右端点排序,然后依次枚举a[i],pos[a[i]]表示对于数字a[i],上一个位置在哪
那么只需要将pos[a[i]]与i之间的部分全部加上a[i]
当查询的右区间为当前更新的位置的时候,查询便是历史区间最值。
但是实现起来并不简单~~~
维护4个值:old_cover 历史最大更新 old_max 历史最大值
now_cover 当前的更新值 now_max 当前区间的最大值
具体的看代码吧,各种纠结,尤其是Push_Down部分
#include<iostream> #include<cstdio> #include<map> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<algorithm> #include<set> #define inf (1ull<<63)-1 #define N 100005 #define maxn 100005 #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define pb(a) push_back(a) #define mem(a,b) memset(a,b,sizeof(a)) #define eps 1e-9 #define zero(a) fabs(a)<eps #define LL long long #define ULL unsigned long long #define lson (step<<1) #define rson (step<<1|1) #define MOD 1000000007 #define mp(a,b) make_pair(a,b) using namespace std; struct Node{ int left,right; int old_max,now_max,old_cover,now_cover; }L[N*4]; struct Que{ int left,right,id; bool operator<(const Que t)const{ return right<t.right; } }Q[N]; int n,q,a[N],pos[N*2+5],ans[N]; void Bulid(int step,int l,int r){ L[step].left=l; L[step].right=r; L[step].old_max=L[step].now_max=L[step].now_cover=L[step].old_cover=0; if(l==r) return; int m=(l+r)/2; Bulid(lson,l,m); Bulid(rson,m+1,r); } void Push_Down(int step){ L[lson].old_cover=max(L[lson].old_cover,L[lson].now_cover+L[step].old_cover); L[rson].old_cover=max(L[rson].old_cover,L[rson].now_cover+L[step].old_cover); L[lson].old_max=max(L[lson].old_max,L[lson].now_max+L[step].old_cover); L[rson].old_max=max(L[rson].old_max,L[rson].now_max+L[step].old_cover); L[lson].now_cover+=L[step].now_cover; L[rson].now_cover+=L[step].now_cover; L[lson].now_max+=L[step].now_cover; L[rson].now_max+=L[step].now_cover; L[step].now_cover=L[step].old_cover=0; } void Push_Up(int step){ L[step].now_max=max(L[lson].now_max,L[rson].now_max); L[step].old_max=max(L[lson].old_max,L[rson].old_max); } void Update(int step,int l,int r,int c){ if(L[step].left==l&&L[step].right==r){ L[step].old_cover=max(L[step].old_cover,L[step].now_cover+=c); L[step].old_max=max(L[step].old_max,L[step].now_max+=c); return; } Push_Down(step); int m=(L[step].left+L[step].right)/2; if(r<=m) Update(lson,l,r,c); else if(l>m) Update(rson,l,r,c); else{ Update(lson,l,m,c); Update(rson,m+1,r,c); } Push_Up(step); } int Query(int step,int l,int r){ if(L[step].left==l&&L[step].right==r) return L[step].old_max; Push_Down(step); int m=(L[step].left+L[step].right)/2; if(r<=m) return Query(lson,l,r); else if(l>m) return Query(rson,l,r); else return max(Query(lson,l,m),Query(rson,m+1,r)); } int main(){ while(scanf("%d",&n)!=EOF){ Bulid(1,1,n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&q); for(int i=0;i<q;i++){ scanf("%d%d",&Q[i].left,&Q[i].right); Q[i].id=i; } sort(Q,Q+q); mem(pos,0); for(int i=1,j=0;i<=n;i++){ Update(1,pos[a[i]+N]+1,i,a[i]); pos[a[i]+N]=i; while(j<q&&Q[j].right==i){ ans[Q[j].id]=Query(1,Q[j].left,Q[j].right); j++; } if(j>=q) break; } for(int i=0;i<q;i++) printf("%d\n",ans[i]); } return 0; }