zoukankan      html  css  js  c++  java
  • [JSOI2016]灯塔

    Description

    $JSOI$的国境线上有$N$一座连续的山峰,其中第$i$座的高度是$h_i$​​.为了简单起见,我们认为这$N$座山峰排成了连续一条直线.

    如果在第$i$座山峰上建立一座高度为$p(p;geq;0)$的灯塔,$JYY$发现,这座灯塔能够照亮第$j$座山峰,当且仅当满足如下不等式:

    $h_j;leq;h_i+p+sqrt{|i-j|}$

    $JSOI$国王希望对于每一座山峰,$JYY$都能提供建造一座能够照亮全部其他山峰的灯塔所需要的最小高度.你能帮助$JYY$么?

    HINT

    $1<N;leq;10^5,0<h_i;leq;10^9$.

    Solution

    题解过段时间补.

    先贴$Menci$神犇的:

    image

    #include<cmath>
    #include<ctime>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define K 17
    #define N 100001
    struct section{
        int l,r;
    }s[N];
    int st[N][K],h[N],m[N],sq[N],log_2[N],n,ans;
    double k;
    inline int read(){
        int ret=0;char c=getchar();
        while(!(c>='0'&&c<='9'))
            c=getchar();
        while(c>='0'&&c<='9'){
            ret=ret*10+c-'0';c=getchar();
        }
        return ret;
    }
    inline int sqr(int k){
        return k*k;
    }
    inline int max(int x,int y){
        return x>y?x:y;
    } 
    inline void ini_st(){
        log_2[1]=0;
        for(int i=2;i<=n;i++){
            log_2[i]=log_2[i-1];
            if((1<<log_2[i]+1)==i)/*pow(2,log_2[i]+1)==i*/
                log_2[i]++;
        }
        for(int i=n;i>=1;i--){
            st[i][0]=h[i];
            for(int j=1;(i+(1<<j)-1)<=n;j++)
                st[i][j]=max(st[i][j-1],st[i+(1<<j-1)][j-1]);
        }
    }
    inline int ask(int l,int r){
        if(l<1) l=1;
        if(r>n) r=n;
        int len=r-l+1,k=log_2[len];
        return max(st[l][k],st[r-(1<<k)+1][k]);
    }
    inline void init(){
        scanf("%d",&n);
        k=sqrt(n);
        int l=(int)(k);
        if(k>l) l++; 
        for(int i=1;i<=n;i++)
            scanf("%d",&h[i]);
        for(int i=1;i<=l;i++){
            s[i].l=sqr(i-1)+1;
            s[i].r=sqr(i);
            for(int j=s[i].l;j<=s[i].r;j++)
                sq[j]=i;
        }
        ini_st();
        for(int i=1;i<=n;i++,ans=0){
            for(int j=sq[i-1];j>=1;j--){
                ans=max(ans,ask(i-s[j].r,i-s[j].l)+j);
            }
            for(int j=sq[n-i];j>=1;j--){
                ans=max(ans,ask(i+s[j].l,i+s[j].r)+j);
            }
            printf("%d
    ",max(0,ans-h[i]));
        }
    }
    int main(){
        freopen("light.in","r",stdin);
        freopen("light.out","w",stdout);
        init();
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    在operator =中要处理“自我赋值”
    delete指针以后应赋值为NULL
    【转】C++对成员访问运算符->的重载
    【转】浅析SkipList跳跃表原理及代码实现
    【KakaJSON手册】05_JSON转Model_05_动态模型
    【KakaJSON手册】04_JSON转Model_04_值过滤
    【KakaJSON手册】03_JSON转Model_03_key处理
    【KakaJSON手册】02_JSON转Model_02_数据类型
    【KakaJSON手册】01_JSON转Model_01_基本用法
    利用eclipse调试JDK源码
  • 原文地址:https://www.cnblogs.com/AireenYe/p/6270542.html
Copyright © 2011-2022 走看看