zoukankan      html  css  js  c++  java
  • [决策单调性][整体二分] Bzoj P2216 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

    题解

    • 随手化简就可以得到p>=aj-ai+sqrt(|i-j|) 
    • 我们发现其实只要求max(aj+sqrt(|i-j|))就好了
    • 不难发现这是有决策单调性的,那么就可以用整体二分来实现
    • 具体方法是二分一个中点mid,然后暴力求出mid的值,再把序列分成两半即可

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm> 
     6 #include <cstdlib>
     7 using namespace std;
     8 const int N=500010;
     9 int n,a[N],id[N];
    10 double ans[N],f[N];
    11 double get(int x,int y) { return a[x]+f[abs(x-y)]; }
    12 void cdq(int l,int r,int L,int R)
    13 {
    14     if (l>r) return;
    15     int mid=l+r>>1,pos=0; double mx=0;
    16     for (int i=L;i<=R&&i<=mid;i++) if (get(i,mid)>mx) mx=get(i,mid),pos=i;
    17     ans[id[mid]]=max(ans[id[mid]],mx),cdq(l,mid-1,L,pos),cdq(mid+1,r,pos,R);
    18 } 
    19 int main()
    20 {
    21     scanf("%d",&n);
    22     for (int i=1;i<=n;i++) scanf("%d",&a[i]),f[i]=sqrt(i),id[i]=i;
    23     cdq(1,n,1,n);
    24     for (int i=1;i<=n/2;i++) swap(a[i],a[n-i+1]),swap(id[i],id[n-i+1]);
    25     cdq(1,n,1,n);
    26     for (int i=1;i<=n;i++) printf("%d
    ",(int)ceil(ans[i]-a[n-i+1]));
    27 } 
  • 相关阅读:
    你知道线框图和原型有啥区别吗
    Git 创建与合并分支
    Java 多态 接口继承等学习笔记
    JAVA多线程之生产者 消费者模式 妈妈做面包案例
    Robot Framework自动化测试(一)---第一个脚本
    仲夏之夜
    vulstack红队评估(一)
    CVE-2017-7269-iis远程溢出漏洞复现
    JMeter 控件整理
    JMeter函数整理
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11145893.html
Copyright © 2011-2022 走看看