BZOJ2216 : [Poi2011]Lightning Conductor

$f[i]=max(a[j]+lceilsqrt{|i-j|} ceil)$,

拆开绝对值,考虑j<i,则决策具有单调性,j>i同理,

所以可以用分治$O(nlog n)$解决。

#include<cstdio>
#include<cmath>
#define N 500010
int n,i,l,r,mid,a[N],b[N],f[N],g[N];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
void dp1(int l,int r,int dl,int dr){
  if(l>r)return;
  int m=(l+r)>>1,i,dm;double t,fm=0;
  for(i=dl;i<=dr&&i<=m;i++)if((t=std::sqrt(m-i)+a[i])>=fm)dm=i,fm=t;
  f[m]=a[dm]+b[m-dm];
  dp1(l,m-1,dl,dm),dp1(m+1,r,dm,dr);
}
void dp2(int l,int r,int dl,int dr){
  if(l>r)return;
  int m=(l+r)>>1,i,dm;double t,fm=0;
  for(i=dr;i>=dl&&i>=m;i--)if((t=std::sqrt(i-m)+a[i])>=fm)dm=i,fm=t;
  g[m]=a[dm]+b[dm-m];
  dp2(l,m-1,dl,dm),dp2(m+1,r,dm,dr);
}
int main(){
  for(read(n),i=1;i<=n;i++)read(a[i]);
  for(i=1;i<n;i++){
    l=1,r=708;
    while(l<=r){
      mid=(l+r)>>1;
      if(mid*mid>=i)r=(b[i]=mid)-1;else l=mid+1;
    }
  }
  dp1(1,n,1,n),dp2(1,n,1,n);
  for(i=1;i<=n;i++)printf("%d
",(f[i]>g[i]?f[i]:g[i])-a[i]);
  return 0;
}

  

原文地址:https://www.cnblogs.com/clrs97/p/4603021.html