bzoj2216: [Poi2011]Lightning Conductor

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://hzwer.com/5273.html
code:
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cassert>
 5 #include<cstring>
 6 #include<algorithm>
 7 using namespace std;
 8 char ch;
 9 bool ok;
10 void read(int &x){
11     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
12     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
13     if (ok) x=-x;
14 }
15 const int maxn=500005;
16 int n,a[maxn],ans[maxn],root[maxn];
17 double calc(int j,int i){return a[j]-a[i]+sqrt(i-j);}
18 struct Stack{
19     int top,pos;
20     struct Data{
21         int l,r,id;
22     }s[maxn],tmp;
23     void init(){s[top=1]=(Data){2,n,1},pos=1;}
24     bool cmp(int a,int x,int y){return calc(x,a)>calc(y,a);}
25     int get(int id){
26         int l=tmp.l,r=tmp.r,m,a=tmp.id;
27         while (l<r){
28             m=((l+r)>>1)+1;
29             if (cmp(m,a,id)) l=m; else r=m-1;
30         }
31         return l;
32     }
33     void push(int id){
34         while (top>=pos&&!cmp(s[top].l,s[top].id,id)) top--;
35         if (top>=pos){
36             tmp=s[top--];
37             int m=get(id);
38             if (tmp.l<=m) s[++top]=(Data){tmp.l,m,tmp.id};
39             if (m<n) s[++top]=(Data){m+1,n,id};
40         }
41         else s[++top]=(Data){id+1,n,id};
42     }
43     int query(int x){
44         while (x>s[pos].r) pos++;
45         s[pos].l=x+1;
46         return ceil(calc(s[pos].id,x));
47     }
48 }stack;
49 int main(){
50     read(n);
51     for (int i=1;i<=n;i++) read(a[i]);
52     stack.init();
53     for (int i=2;i<=n;i++) ans[i]=max(0,stack.query(i)),stack.push(i);
54     for (int i=1,j=n;i<j;i++,j--) swap(a[i],a[j]);
55     stack.init();
56     for (int i=2;i<=n;i++) ans[n-i+1]=max(ans[n-i+1],stack.query(i)),stack.push(i);
57     for (int i=1;i<=n;i++) printf("%d\n",ans[i]);
58     return 0;
59 }

 

posted @ 2016-03-10 16:21  chenyushuo  阅读(303)  评论(0编辑  收藏  举报