zoukankan      html  css  js  c++  java
  • HDU 4417:Super Mario(主席树)

    http://acm.hdu.edu.cn/showproblem.php?pid=4417

    题意是:给出n个数和q个询问,每个询问有一个l,r,h,问在[l,r]这个区间里面有多少个数是小于等于h的。

    思路:比较裸的主席树,注意题意给的区间是从[0,n-1],一开始看错导致想错了很多东西。询问的时候如果m < h,那么左子树全部都是小于 h 的,就加上左子树的 sum,继续查右子树,否则就查左子树。最后 l == r 的时候要判下 h >= l,因为这个也错了几次。从师兄那里学习到了如果找一个数,如果找不到就返回一个比它小的数,那么可以用 upper_bound() 找到的下标 -1。就不用 lower_bound() 找到后判断等不等于,不等于的话下标 -1 这么麻烦了。(upper_bound()返回的是大于查的数的下标,所以 -1就可以等于或者小于了。)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 using namespace std;
     6 #define N 100010
     7 struct node
     8 {
     9     int l, r, sum;
    10 }tree[N*40];
    11 int root[N], tot, a[N], b[N], cnt;
    12 
    13 void update(int pre, int &now, int id, int l, int r)
    14 {
    15     now = ++tot; tree[now] = tree[pre];
    16     tree[now].sum++;
    17     if(l == r) return ;
    18     int m = (l + r) >> 1;
    19     if(id <= m) update(tree[pre].l, tree[now].l, id, l, m);
    20     else update(tree[pre].r, tree[now].r, id, m + 1, r);
    21 }
    22 
    23 int query(int L, int R, int h, int l, int r)
    24 {
    25     int ans = 0;
    26     int m = (l + r) >> 1;
    27     if(l == r) {
    28         if(h >= l) ans += tree[R].sum - tree[L].sum; // 注意要判下这个
    29         /*
    30         如果区间查询和更新的区间是(0, cnt)的话,那么就可以不用判定这个
    31         因为如果查的区间是(3, 5, 5) 查 2 的话,那么会查到下标 0,
    32         l > h,这个时候就错了
    33         */
    34         return ans;
    35     }
    36     if(m < h) {
    37         ans += tree[tree[R].l].sum - tree[tree[L].l].sum; // 如果 h > m 的话,左子树全部都小于h,全部都加上
    38         ans += query(tree[L].r, tree[R].r, h, m + 1, r);
    39     } else {
    40         ans += query(tree[L].l, tree[R].l, h, l, m);
    41     }
    42     return ans;
    43 }
    44 
    45 void debug(int rt, int l, int r)
    46 {
    47     if(l == r) {
    48         printf("%d : %d
    ", l, tree[rt].sum);
    49         return ;
    50     }
    51     int m = (l + r) >> 1;
    52     debug(tree[rt].l, l, m);
    53     debug(tree[rt].r, m+1, r);
    54 }
    55 
    56 int main()
    57 {
    58     int t, cas = 1;
    59     scanf("%d", &t);
    60     while(t--) {
    61         int n, q;
    62         scanf("%d%d", &n, &q);
    63 
    64         tot = 0;
    65 
    66         for(int i = 1; i <= n; i++) {
    67             scanf("%d", &a[i]);
    68             b[i] = a[i];
    69         }
    70         sort(b + 1, b + 1 + n);
    71         cnt = unique(b + 1, b + 1 + n) - b - 1;
    72         for(int i = 1; i <= n; i++) {
    73             a[i] = lower_bound(b + 1, b + 1 + cnt, a[i]) - b;
    74             update(root[i-1], root[i], a[i], 1, cnt);
    75         }
    76         debug(root[n], 1, cnt);
    77         printf("Case %d:
    ", cas++);
    78         for(int i = 1; i <= q; i++) {
    79             int l, r, c;
    80             scanf("%d%d%d", &l, &r, &c);
    81             l++, r++;
    82             int tmp = upper_bound(b + 1, b + 1 + cnt, c) - b - 1;
    83 //            int tmp = lower_bound(b + 1, b + 1 + cnt, c) - b;
    84 //            if(b[tmp] != c) tmp--;
    85 //            int tmp = lb(c);
    86             printf("%d
    ", query(root[l-1], root[r], tmp, 1, cnt));
    87         }
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    用代码初始化AE控件许可
    打开shpfile,mdb,sde工作空间
    UESTC_Tournament CDOJ 124
    UESTC_Little Deer and Blue Cat CDOJ 1025
    UESTC_Judgment Day CDOJ 11
    UESTC_One Step Two Steps CDOJ 1027
    UESTC_In Galgame We Trust CDOJ 10
    UESTC_贪吃蛇 CDOJ 709
    UESTC_冰雪奇缘 CDOJ 843
    java 常用API 时间
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6031243.html
Copyright © 2011-2022 走看看