zoukankan      html  css  js  c++  java
  • Codeforces Round #305 (Div. 2)——D单调/路径压缩——Mike and Feet

    Mike is the president of country What-The-Fatherland. There are n bears living in this country besides Mike. All of them are standing in a line and they are numbered from 1 to n from left to right. i-th bear is exactly ai feet high.

    A group of bears is a non-empty contiguous segment of the line. The size of a group is the number of bears in that group. The strengthof a group is the minimum height of the bear in that group.

    Mike is a curious to know for each x such that 1 ≤ x ≤ n the maximum strength among all groups of size x.

    Input

    The first line of input contains integer n (1 ≤ n ≤ 2 × 105), the number of bears.

    The second line contains n integers separated by space, a1, a2, ..., an (1 ≤ ai ≤ 109), heights of bears.

    Output

    Print n integers in one line. For each x from 1 to n, print the maximum strength among all groups of size x.

    Sample test(s)
    input
    10
    1 2 3 4 5 4 3 2 1 6
    output
    6 4 4 3 3 2 2 1 1 1 
    法一:
    大意:对于size从1到n,让你求对应于每一个size的区间内最小的值里面的最大的值,比如size = 2 最小就分别为 1 2 3 4 4 3 2 1 1所以第二个值为4
    用了单调栈的思想,让下标对于的值严格减,那么对于每一个值而言,前面已经标记过的都是比他大的,而其他都是比他小的或者相等,这样得到的区间就是最小的区间而值最大,(容易看出区间越小值就应该让他越大比如 1 3 5 size为1可以取到5,而size为2时就是次大),防止TLE,压缩寻找的时候的路径
    O(nlogn)
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 200010;
    int l[maxn],r[maxn],ord[maxn];
    int a[maxn],ans[maxn],vis[maxn];
    bool cmp(int i,int j){
        return a[i] > a[j];
    }
    int find_l(int x){
        if(!vis[l[x]-1])
            return l[x];
        else {
            return l[x] = find_l(l[x]-1);
        }
    }
    int find_r(int x){
        if(!vis[r[x]+1])
            return r[x];
        else {
            return r[x] = find_r(r[x]+1);
        }
    }
    int main()
    {
        int n;
        while(~scanf("%d%",&n)){
            memset(vis,0,sizeof(vis));
            for(int i = 1; i <= n ;i++)
                scanf("%d",&a[i]);
            for(int i = 1; i <= n ;i++){
                l[i] = r[i] = ord[i] = i;
            }
            sort(ord+1,ord+n+1,cmp);
           // for(int i = 1; i <= n;i++)
           //     printf("%d ",ord[i]);
            int j = 1;
            for(int i = 1; i <= n ;i++){
                int tmp = ord[i];
                vis[tmp] = 1;
                while(j <= find_r(tmp) - find_l(tmp) + 1){
                    ans[j] = a[ord[i]];
                 //   printf("%d %d
    ",find_r(i),find_l(i));
                    j++;
                   // printf("%d ",j);
                }
            }
            for(int i = 1; i <= n; i++){
            if(i == 1) printf("%d",ans[i]);
            else printf(" %d",ans[i]);
            }
            puts("");
        }
        return 0;
    }
    

     法二:用路径压缩的思想,对于每一个a[i]都能得出他的l[i]跟r[i],那么用一个res数组来保存以该长度的值,比这个长度小的都可以更新成这个数(因为长度都是由a[i]产生的),之后倒着对res更新

    O(n)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 200010;
    int l[maxn],r[maxn];
    int a[maxn],res[maxn];
    int main()
    {
        int n;
        while(~scanf("%d",&n)){
            for(int i = 1; i <= n ;i++){
                scanf("%d",&a[i]);
                l[i] = r[i] = i;
            }
            for(int i = 1; i <= n ;i++){
                while(l[i]-1 >= 1 && a[l[i]-1] >= a[i])
                    l[i] = l[l[i]-1];
            }
            for(int i = 1; i <= n ;i++){
                while(r[i]+1 <= n && a[r[i]+1] >= a[i])
                    r[i] = r[r[i]+1];
            }
            for(int i =1 ; i<= n; i++)
                res[r[i]-l[i]+1] = a[i];
            for(int i = n-1 ;i >= 1; i--)
                res[i] = max(res[i],res[i+1]);
            for(int i = 1; i <= n ;i++){
                if(i == 1) printf("%d",res[i]);
                else printf(" %d",res[i]);
            }
            puts("");
        }
            return 0;
    
    }
    

      

     

     
  • 相关阅读:
    01 Jq 基础
    01 属性
    input 编辑框 光标 的相关问题
    登录页面 文字 2 3 4 个字 等宽俩端对齐 空格
    复选框单选框与文字对齐问题的研究与解决
    在Python中对MySQL中的数据进行可视化
    输入2个坐标的数值求出对应坐标间的距离和圆的面积
    numpy中arange函数内起始值必须大于结束值,否则生成为空的一维数组
    条件语句练习-比分预测
    三元表达式是棒棒哒!
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4536099.html
Copyright © 2011-2022 走看看