• Hdu 2795 线段树 区间最大值的位置.cpp


    题意:

      一个board的面积是h*w..在上面贴一些announcement..

      给出告示的宽度ww..可知告示的面积为1*ww..

      问告示是否可以贴上去..可以就输出在board的第几行..不可以就输出-1

     

    思路:

      以min(h, n)为长度建一棵树..

      然后每一个的叶子的长度为w..

      找出所有叶子中最大的那个..把announcement贴上去..

      用ma数组存当前区间最大值..

     

    Tips:

      查询和更新可以一起写..但是我分开写了..

      然后还有一个要注意的是..树的最大宽度为min(h, n)
      比较的时候是和左右节点大小比..

      ※ 所以modify的时候判断条件也应该是if(x > ma[rt<<1])..

      

     

    Code:

    View Code
     1 #include <stdio.h>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int MAXN = 200010;
     7 int ma[MAXN<<2];
     8 int h, w, n;
     9 
    10 void pushup(int rt)
    11 {
    12     ma[rt] = max(ma[rt<<1], ma[rt<<1|1]);
    13 }
    14 
    15 void creat(int l, int r, int rt)
    16 {
    17     ma[rt] = w;
    18     if(l == r)
    19         return;
    20     int mid = (l+r)>>1;
    21     creat(l, mid, rt<<1);
    22     creat(mid+1, r, rt<<1|1);
    23 }
    24 
    25 void modify(int p, int ww, int l, int r, int rt)
    26 {
    27     if(l == r) {
    28         ma[rt] += ww;
    29         return;
    30     }
    31     int mid = (l+r)>>1;
    32     if(p <= mid) modify(p, ww, l, mid, rt<<1);
    33     else modify(p, ww, mid+1, r, rt<<1|1);
    34     pushup(rt);
    35 }
    36 
    37 int query(int x, int L, int R, int rt)
    38 {
    39     if(L == R) {
    40         return L;
    41     }
    42     int mid = (L+R)>>1;
    43     int res = 0;
    44     if(x <= ma[rt<<1]) query(x, L, mid, rt<<1);
    45     else query(x, mid+1, R, rt<<1|1);
    46 }
    47 
    48 int main()
    49 {
    50     int i, j;
    51     int ww;
    52     int ans;
    53     while(scanf("%d %d %d", &h, &w, &n) != EOF)
    54     {
    55         if(h > n) h = n;
    56         creat(1, h, 1);
    57 
    58         for(i = 0; i < n; ++i) {
    59             scanf("%d", &ww);
    60             if(ww > ma[1]) puts("-1");
    61             else {
    62                 ans = query(ww, 1, h, 1);
    63                 printf("%d\n", ans);
    64                 modify(ans, -ww, 1, h, 1);
    65             }
    66 
    67         }
    68     }
    69     return 0;
    70 }

     

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795

  • 相关阅读:
    C# Process执行bat
    Auto Clear Unity Console Log
    Unity原厂讲师大解密
    setSystemUiVisibility() 与 getSystemUiVisibility() 显示隐藏状态栏
    Android 6.0 动态权限申请
    Android6.0动态权限申请步骤以及需要注意的一些坑
    基于Rebound制造绚丽的动画效果-入门篇
    Rebound-Android的弹簧动画库
    Rebound动画框架简单介绍
    让动画不再僵硬:Facebook Rebound Android动画库介绍
  • 原文地址:https://www.cnblogs.com/Griselda/p/2719741.html
Copyright © 2020-2023  润新知