zoukankan      html  css  js  c++  java
  • set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet

    题目传送门

      1 /*
      2     题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值
      3     set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中
      4                 查找左右相邻的位置,更新长度为r - l - 1的最大值,感觉线段树结构体封装不错!
      5     详细解释:http://blog.csdn.net/u010660276/article/details/46045777
      6     其实还有其他解法,先掌握这种:)
      7 */
      8 #include <cstdio>
      9 #include <algorithm>
     10 #include <iostream>
     11 #include <iostream>
     12 #include <cstring>
     13 #include <set>
     14 using namespace std;
     15 
     16 typedef long long ll;
     17 #define lson l, mid, rt << 1
     18 #define rson mid + 1, r, rt << 1 | 1
     19 
     20 const int MAXN = 2e5 + 10;
     21 const int INF = 0x3f3f3f3f;
     22 
     23 struct A
     24 {
     25     int v, id;
     26     bool operator < (const A &a) const
     27     {
     28         return v < a.v;
     29     }
     30 }a[MAXN];
     31 struct SegmentTree
     32 {
     33     int add[MAXN << 2];
     34     int mx[MAXN << 2];
     35 
     36     void push_down(int rt)
     37     {
     38         if (add[rt])
     39         {
     40             add[rt<<1] = add[rt<<1|1] = add[rt];
     41             mx[rt<<1] = mx[rt<<1|1] = add[rt];
     42             add[rt] = 0;
     43         }
     44     }
     45 
     46     void build(int l, int r, int rt)
     47     {
     48         add[rt] = mx[rt] = 0;
     49         if (l == r)    return ;
     50         int mid = (l + r) >> 1;
     51         build (lson);    build (rson);
     52     }
     53 
     54     void updata(int ql, int qr, int c, int l, int r, int rt)
     55     {
     56         if (ql <= l && r <= qr)    {mx[rt] = c; add[rt] = c;    return ;}
     57         push_down (rt);
     58         int mid = (l + r) >> 1;
     59         if (ql <= mid)    updata (ql, qr, c, lson);
     60         if (qr > mid)    updata (ql, qr, c, rson);
     61     }
     62 
     63     int query(int x, int l, int r, int rt)
     64     {
     65         if (l == r)    return mx[rt];
     66         push_down (rt);
     67         int mid = (l + r) >> 1;
     68         if (x <= mid)    return query (x, lson);
     69         return query (x, rson);
     70     }
     71 }tree;
     72 
     73 int ans[MAXN];
     74 
     75 int main(void)        //Codeforces Round #305 (Div. 2) D. Mike and Feet
     76 {
     77     int n;
     78     while (scanf ("%d", &n) == 1)
     79     {
     80         for (int i=1; i<=n; ++i)
     81         {
     82             scanf ("%d", &a[i].v);    a[i].id = i;
     83         }
     84         sort (a+1, a+1+n);
     85 
     86         tree.build (1, n, 1);
     87         set<int> S;    S.insert (0);    S.insert (n + 1);
     88         set<int>::iterator it;
     89         for (int i=1; i<=n; ++i)
     90         {
     91             int l, r;
     92             it = S.lower_bound (a[i].id);
     93             r = *it; it--; l = *it;
     94             if (r - l - 1 >= 1)    tree.updata (1, r-l-1, a[i].v, 1, n, 1);
     95             S.insert (a[i].id);
     96         }
     97 
     98         for (int i=1; i<=n; ++i)
     99             ans[i] = tree.query (i, 1, n, 1);
    100         for (int i=1; i<=n; ++i)
    101             printf ("%d%c", ans[i], (i==n) ? '
    ' : ' ');
    102     }
    103 
    104     return 0;
    105 }
    106 
    107 /*
    108 10
    109 1 2 3 4 5 4 3 2 1 6
    110 */

     

     1 /*
     2     jinye的解法:原理一样,找到最小值是a[i]的最长区间,用l[],r[]记录左右端点的位置
     3                 比线段树快多了:)
     4 */
     5 #include <cstdio>
     6 #include <iostream>
     7 #include <algorithm>
     8 #include <cstring>
     9 #include <cmath>
    10 using namespace std;
    11 
    12 const int MAXN = 2e5 + 10;
    13 const int INF = 0x3f3f3f3f;
    14 int a[MAXN], l[MAXN], r[MAXN], ans[MAXN];
    15 
    16 int main(void)        //Codeforces Round #305 (Div. 2) D. Mike and Feet
    17 {
    18     int n;
    19     while (scanf ("%d", &n) == 1)
    20     {
    21         memset (ans, 0, sizeof (ans));
    22         for (int i=1; i<=n; ++i)
    23         {
    24             scanf ("%d", &a[i]);
    25             l[i] = r[i] = i;
    26         }
    27 
    28         for (int i=1; i<=n; ++i)
    29         {
    30             while (l[i] > 1 && a[i] <= a[l[i]-1])    l[i] = l[l[i]-1];
    31         }
    32         for (int i=n; i>=1; --i)        //倒过来回超时
    33         {
    34             while (r[i] < n && a[i] <= a[r[i]+1])    r[i] = r[r[i]+1];
    35         }
    36 
    37         for (int i=1; i<=n; ++i)
    38         {
    39             int x = r[i] - l[i] + 1;
    40             ans[x] = max (ans[x], a[i]);
    41         }
    42 
    43         for (int i=n-1; i>=1; --i)        //可能范围扩展的太厉害了
    44         {
    45             ans[i] = max (ans[i], ans[i+1]);
    46         }
    47 
    48         for (int i=1; i<=n; ++i)
    49             printf ("%d%c", ans[i], (i==n) ? '
    ' : ' ');
    50     }
    51 
    52     return 0;
    53 }
    数组效率更高
    编译人生,运行世界!
  • 相关阅读:
    安利一个_Java学习笔记总结
    九涯的第一次
    attrs 资源文件 自定义属性
    EditText
    ArrayList 数组 初始化方法
    HTTP Retrofit 网络传输
    画布Canvas 画笔Paint
    View控件跟随鼠标移动
    ViewPager和Fragment中的View的点击事件冲突
    圆形图片 ImageView
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4534187.html
Copyright © 2011-2022 走看看