回复 2楼 czz5242199
嗯嗯,听朋友说要用线段树,能讲解下否?
回复 8楼 czz5242199
ACM就肯定谈不上了……
#include <stdio.h> #include <stdlib.h> int a[100001],n,m,L,R,i,j,ans,now,pi,pj; int main() { scanf("%d%d",&n,&m); for (i=1; i<=n; i++) scanf("%d",a+i); while (m--) { scanf("%d%d",&L,&R); ans=-10001; now=0; i=L; for (j=L; j<=R; j++) { if (now>=0) now+=a[j]; else { now=a[j]; i=j; } if (now>ans) { pi=i; pj=j; ans=now; } } printf("%d %d %d\n",pi,pj,ans); } return 0; }
#include <stdio.h> #include <stdlib.h> #include <math.h> int n,m,L,R,ans,a[100001],s[100001],f[100001],pre[100001],RMQ_s[100001][17],RMQ_f[100001][17],two[17]; void dp() { int i,j; s[1]=a[1]; pre[1]=1; f[1]=a[1]; for (i=1; i<=n; i++) { s[i]=s[i-1]+a[i]; if (f[i-1]>=0) { f[i]=f[i-1]+a[i]; pre[i]=pre[i-1]; } else { f[i]=a[i]; pre[i]=i; } } } void Prepare_RMQ_S() { int i,j=log(n)/log(2),k; for (i=1; i<=n; i++) RMQ_s[i][0]=i; for (k=1; k<=j; k++) for (i=1; i<n; i++) { if (i+two[k]-1>n) break; if (s[RMQ_s[i][k-1]]<s[RMQ_s[i+two[k-1]][k-1]]) RMQ_s[i][k]=RMQ_s[i][k-1]; else RMQ_s[i][k]=RMQ_s[i+two[k-1]][k-1]; } } void Prepare_RMQ_F() { int i,j=log(n)/log(2),k; for (i=1; i<=n; i++) RMQ_f[i][0]=i; for (k=1; k<=j; k++) for (i=1; i<n; i++) { if (i+two[k]-1>n) break; if (f[RMQ_f[i][k-1]]>f[RMQ_f[i+two[k-1]][k-1]]) RMQ_f[i][k]=RMQ_f[i][k-1]; else RMQ_f[i][k]=RMQ_f[i+two[k-1]][k-1]; } } int Get_RMQ_C(int p,int q) { int l=log(q-p+1)/log(2); if (s[RMQ_s[p][l]]<=s[RMQ_s[q-two[l]+1][l]]) return RMQ_s[p][l]; else return RMQ_s[q-two[l]+1][l]; } int Get_RMQ_F(int p,int q) { int l=log(q-p+1)/log(2); if (f[RMQ_f[p][l]]>=f[RMQ_f[q-two[l]+1][l]]) return RMQ_f[p][l]; else return RMQ_f[q-two[l]+1][l]; } void FindMaxL() { int p,q,t,ans,GL,GR; p=Get_RMQ_F(L,R); if (pre[p]>=L) printf("%d %d %d\n",pre[p],p,f[p]); else { q=Get_RMQ_C(L-1,p-1); ans=s[p]-s[q]; GL=q+1,GR=p; while (p<R) { p=Get_RMQ_F(p+1,R); if (pre[p]>=L) { if (ans<f[p]) { ans=f[p]; GL=pre[p]; GR=p; } break; } q=Get_RMQ_C(L-1,p-1); if (ans<s[p]-s[q]) { ans=s[p]-s[q]; GL=q+1; GR=p; } } printf("%d %d %d\n",GL,GR,ans); } } int main() { int i; scanf("%d%d",&n,&m); for (i=1; i<=n; i++) scanf("%d",&a[i]); two[0]=1; for (i=1; i<=16; i++) two[i]=two[i-1]*2; dp(); Prepare_RMQ_S(); Prepare_RMQ_F(); while (m--) { scanf("%d%d",&L,&R); FindMaxL(); } return 0; }