回复 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;
}