【bzoj2216】[Poi2011]Lightning Conductor 1D1D动态规划优化

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 }

原文地址:https://www.cnblogs.com/fengzhiyuan/p/8185109.html

时间: 2024-08-03 03:58:22

【bzoj2216】[Poi2011]Lightning Conductor 1D1D动态规划优化的相关文章

bzoj2216: [Poi2011]Lightning Conductor(分治决策单调性优化)

每个pi要求 这个只需要正反DP(?)一次就行了,可以发现这个是有决策单调性的,用分治优化 #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int maxn=500010,inf=1e9; int n; int a[

P3515 [POI2011]Lightning Conductor[决策单调性优化]

给定一序列,求对于每一个$a_i$的最小非负整数$p_i$,使得$\forall j \neq i $有$ p_i>=a_j-a_i+ \sqrt{|i-j|}$. 绝对值很烦 ,先分左右情况单独做.现在假设j都在i左边,则$p_i=max{a_j-a_i+ \sqrt{i-j}}=max{a_j+ \sqrt{i-j} }-a_i$.带根号,不易斜率优化,考虑证决策单调性. 假设最优决策为j,j之前的任意决策称之为$j'$,则有 $f[j]+\sqrt{i-j} \geqslant f[j']

BZOJ2216 : [Poi2011]Lightning Conductor

$f[i]=\max(a[j]+\lceil\sqrt{|i-j|}\rceil)$, 拆开绝对值,考虑j<i,则决策具有单调性,j>i同理, 所以可以用分治$O(nlogn)$解决. #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())

【BZOJ2216】[Poi2011]Lightning Conductor 决策单调性

[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 I

1D1D动态规划优化

1D1D动态规划优化 1D/1D 动态规划优化初步所谓1D/1D 动态规划,指的是状态数为O(n),每一个状态决策量为O(n)的动态规划方程.直接求解的时间复杂度为O(n2),但是,绝大多数这样的方程通过合理的组织与优化都是可以优化到O(nlogn)乃至O(n)的时间复杂度的.这里就想讲一讲我对一些比较初步的经典的优化方法的认识.本文中不想进行过多的证明与推导,主要想说明经典模型的建立.转化与求解方法.由于本人认识与水平相当有限,如果出现什么错误与疏漏,还请大牛多多指正.另外,也希望大牛们更多地

P3515 [POI2011]Lightning Conductor(决策单调性分治)

P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下面给一张图证明这是满足决策单调性的 把$a_j+sqrt(i-j)$表示在坐标系上 显然$sqrt(i-j)$的增长速度趋缓 曲线$a$被曲线$b$超过后是无法翻身的 对两个方向进行决策单调性分治,取$max$即可 #include<iostream> #include<cstdio>

@bzoj - [email&#160;protected] [Poi2011]Lightning Conductor

目录 @[email protected] @[email protected] @part - [email protected] @part - [email protected] @part - [email protected] @accepted [email protected] @version - [email protected] @version - [email protected] @[email protected] @[email protected] 已知一个长度为

[POI2011]Lightning Conductor

题面在这里 description 已知一个长度为\(n\)的序列\(a_1,a_2,...,a_n\). 对于每个\(1\le i\le n\),找到最小的非负整数\(p\), 满足对于任意的\(1\le j\le n\),\(a_j\le a_i+p-\sqrt{|i-j|}\) data range \[n\le 5\times 10^5,a_i\le 10^9\] solution 绝对值怎么办? 我们先从左到右\(DP\ j< i\)的部分(此时有\(|i-j|=i-j\)), 再右到

P3515 [POI2011]Lightning Conductor

首先进行一步转化 $a_j \leq a_i + q - sqrt(abs(i - j))$ $a_i + q \geq a_j + sqrt(abs(i-j))$ 即 $q = max (a_j + sqrt(abs(i-j))) - a_i $ 我们对$i \geq j 和 j > i$ 分类讨论, 其实解决一种情况后将序列翻转再做一遍即可 有一种O($n^2$)的dp暴力应该不难想到 那么我们现在思考如何以比较优秀的时间复杂度解决 这里涉及到决策单调性 简单的说, 对于i来说, 它的答案来