[BZOJ2216][POI2011]Lightning Conductor && 1D1D

来源:互联网 发布:java冒泡排序代码详解 编辑:程序博客网 时间:2024/05/22 07:02

题目描述

已知一个长度为n的序列a1,a2,...,an。
对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j))

输入

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

输出

n行,第i行表示对于i,得到的p

样例输入

 (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

6532424

样例输出

235354


#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<cmath>#include<queue>#define SF scanf#define PF printfusing namespace std;typedef long long LL;const int MAXN = 500000;int a[MAXN+10], n;double Left[MAXN+10], Right[MAXN+10];struct Node {    int pos, l, r;    Node () {}    Node (int p, int L, int R) : pos(p), l(L), r(R) {}} Q[MAXN+10];double calc(int i, int j) {    return a[i] + sqrt(abs(i-j));}int search(int L, int R, int i, int j) {    while(L < R) {        int mid = (L + R) >> 1;        if(calc(i, mid) < calc(j, mid)) L = mid+1;        else R = mid;    }    return L;}void dp(double ans[]) {    int F =0, R = 0;    for(int i = 1; i <= n; i++) {        if(F < R && ++Q[F].l > Q[F].r) F++;        if(F >= R || calc(i, n) > calc(Q[R-1].pos, n)) {            while(F < R && calc(i, Q[R-1].l) > calc(Q[R-1].pos, Q[R-1].l)) R--;            if(F >= R) Q[R++] = Node(i, i, n);            else {                int st = search(Q[R-1].l, Q[R-1].r, i, Q[R-1].pos);                Q[R-1].r = st-1; Q[R++] = Node(i, st, n);            }        }        ans[i] = calc(Q[F].pos, i);    }}int main() {    SF("%d", &n);    for(int i = 1; i <= n; i++) SF("%d", &a[i]);    dp(Left); reverse(a+1, a+1+n);     dp(Right); reverse(Right+1, Right+1+n);    reverse(a+1, a+1+n);    for(int i = 1; i <= n; i++) PF("%d\n", (int)ceil(max(Left[i], Right[i]) - a[i]));}



0 0
原创粉丝点击