1. 程式人生 > >【bzoj2216】[Poi2011]Lightning Conductor 1D1D動態規劃優化

【bzoj2216】[Poi2011]Lightning Conductor 1D1D動態規劃優化

規劃 sample long 得到 mes tput stream truct 優化

Description

已知一個長度為n的序列a1,a2,…,an。
對於每個1<=i<=n,找到最小的非負整數p滿足 對於任意的j, aj < = ai + p – sqrt(abs(i-j))

Input

第一行n,(1<=n<=500000)
下面每行一個整數,其中第i行是ai。(0<=ai<=1000000000)

Output

n行,第i行表示對於i,得到的p

Sample Input

6
5
3
2
4
2
4

Sample Output

2
3
5
3
5
4

題解

http://ydcydcy1.blog.163.com/blog/static/2160890402013315391435/

 1 #include<cstring>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstdio>
 6 
 7 #define ll long long
 8 #define N 500007
 9 using namespace std;
10 inline int read()
11 {
12     int x=0,f=1;char ch=getchar();
13     while(ch<
0||ch>9){if (ch==-) f=-1;ch=getchar();} 14 while(ch>=0&&ch<=9){x=(x<<3)+(x<<1)+ch-0;ch=getchar();} 15 return x*f; 16 }int n; 17 int a[N]; 18 double f[N],g[N]; 19 struct data{int l,r,p;}q[N]; 20 double cal(int j,int i) 21 { 22 return a[j]+sqrt(abs(i-j))-a[i];
23 } 24 int find(data t,int x) 25 { 26 int l=t.l,r=t.r; 27 while(l<=r) 28 { 29 int mid=(l+r)>>1; 30 if(cal(t.p,mid)>cal(x,mid)) 31 l=mid+1; 32 else r=mid-1; 33 } 34 return l; 35 } 36 void dp(double *F) 37 { 38 int head=1,tail=0; 39 for(int i=1;i<=n;i++) 40 { 41 q[head].l++; 42 if(head<=tail&&q[head].r<q[head].l)head++; 43 if(head>tail||cal(i,n)>cal(q[tail].p,n)) 44 { 45 while(head<=tail&&cal(q[tail].p,q[tail].l)<cal(i,q[tail].l)) 46 tail--; 47 if(head>tail) 48 q[++tail]=(data){i,n,i}; 49 else 50 { 51 int t=find(q[tail],i); 52 q[tail].r=t-1; 53 q[++tail]=(data){t,n,i}; 54 } 55 } 56 F[i]=cal(q[head].p,i); 57 } 58 } 59 int main() 60 { 61 n=read(); 62 for(int i=1;i<=n;i++)a[i]=read(); 63 dp(f); 64 for(int i=1;i<=n/2;i++)swap(a[i],a[n-i+1]); 65 dp(g); 66 for(int i=1;i<=n;i++) 67 printf("%d\n",max(0,(int)ceil(max(f[i],g[n-i+1])))); 68 return 0; 69 }

【bzoj2216】[Poi2011]Lightning Conductor 1D1D動態規劃優化