• CF212D 【Cutting a Fence】


    AC传送门!

    由于在洛谷发布时,用了大量的LATEX,所以不想在博客园重新打一遍了。

    洛谷博客

    #include <bits/stdc++.h>
    using namespace std;
    #define N 1000010
    #define ll long long
    
    inline ll read(){
        ll x = 0, s = 1;
        char c = getchar();
        while(!isdigit(c)){
            if(c == '-')s = -1;
            c = getchar();
        }
        while(isdigit(c)){
            x = x * 10 + (c ^ '0');
            c = getchar();
        }
        return x * s;
    }
    
    ll n, m, r[N], l[N], a[N];
    ll s1[N], s2[N];
    double ans[N];
    
    void search(){
        for(int i = n; i; i--){  /*向右找到第一个小于等于这个数的位置*/
            if(a[i + 1] <= a[i]) r[i] = i + 1;
            else 
                for(int j = r[i + 1]; j <= n + 1; j = r[j])  /*一直向右跑*/
                    if(a[j] <= a[i]){
                        r[i] = j;
                        break;
                    }
        }
        for(int i = 1;i <= n; i++){  /*同上,向左找*/
            if(a[i - 1] < a[i]) l[i] = i - 1;
            else 
                for(int j = l[i - 1]; j >= 0; j = l[j]) 
                    if(a[j] < a[i]) {
                        l[i] = j;
                        break;
                    }
    
        }
        for(int i = 1;i <= n; i++){  /*换算成距离 L 和 R*/
            l[i] = i - l[i];   
            r[i] = r[i] - i;
        }
        return ;
    }
    
    void prepare(){  /*进行差分以及预处理答案*/
            for(int i = 1;i <= n; i++){
            int x = l[i], y = r[i];
            if(x > y) swap(x, y);  /*保持 L < S*/
            s1[1] += a[i];
            s1[x + 1] -= a[i];
            s2[x + 1] += a[i] * x;
            s1[y + 1] -= a[i];
            s2[y + 1] += a[i] * y;
            s1[x + y] += a[i]; 
            s2[x + y] -= a[i] * (x + y);
        }
        ll num1 = 0, num2 = 0;
        for(int i = 1;i <= n; i++){
            num1 += s1[i], num2 += s2[i];
            ans[i] = ((num1 * i + num2) * 1.00) / ((n - i + 1) * 1.00); /*预处理出所有答案*/
        }
        return ;
    }
    
    int main(){
        n = read();
        for(int i = 1;i <= n; i++)
            a[i] = read();
        a[n + 1] = (ll)(-(1 << 50));/*两端插入极小值,避免下一步越界或者出现错误*/
        a[0] = (ll)(-(1 << 50));
        search(); /*先搜索距离*/
        prepare();  /*然后处理答案*/
        m = read();
        while(m--){
            ll k = read();
            printf("%.9lf
    ", ans[k]);  
        }
        return 0;
    }

     

  • 相关阅读:
    完整的CRUD——javaweb
    JDBC预编译语句表名占位异常
    自定义标签2.x
    实现一个自定义<table>标签
    带动态属性的自定义标签
    自定义标签库_tag
    poj 3783
    The North American Invitational Programming Contest 2018 E. Prefix Free Code
    hdu 6383
    ACM-ICPC 2016 Qingdao Preliminary Contest G. Sort
  • 原文地址:https://www.cnblogs.com/wondering-world/p/13190830.html
Copyright © 2020-2023  润新知