zoukankan      html  css  js  c++  java
  • UPC 2224 Boring Counting ★(山东省第四届ACM程序设计竞赛 tag:线段树)

    [题意]给定一个长度为N的数列,M个询问区间[L,R]内大于等于A小于等于B的数的个数. [题目链接]http://acm.upc.edu.cn/problem.php?id=2224 省赛的时候脑抽想了10min没想出来就看别的题去了= =,赛后又想了10min想出来了并且1Y。。。真嫌弃自己= =。。。 [分析]如果做过询问区间[L,R]内小于H的个数的那道线段树题(HDU 4417 2012年杭州赛区网络赛)那么这题就好想了。那在这里再说一下做法:{将所有的询问离线读入之后,按H从小到大排序。对于所有的区间数也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,然后就是一个区间和}。 那么这题也就简单了。。。按上面方法分别求出区间[L,R]内大于等于A的个数num1和小于等于B的个数num2,然后res = num1 + num2 - [L,R].  
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define MID(x,y) ((x+y)>>1)
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
     
    const int MAXN = 50002;
    struct Segment_Tree{
        int sum[MAXN<<2];
        void build(){
            mem(sum, 0);
        }
        void pushup(int rt){
            sum[rt] = sum[rt<<1] + sum[rt<<1|1];
        }
        void update(int p, int v, int l, int r, int rt){
            if (l == r){
                sum[rt] = v;
                return ;
            }
            int mid = MID(l, r);
            if (p <= mid) update(p, v, l, mid, rt<<1);
            else    update(p, v, mid+1, r, rt<<1|1);
            pushup(rt);
        };
        int query(int l, int r, int L, int R, int rt){
            if (l <= L && R <= r){
                return sum[rt];
            }
            int mid = MID(L,R);
            int ans = 0;
            if (l <= mid)   ans += query(l, r, L, mid, rt<<1);
            if (mid < r)    ans += query(l, r, mid+1, R, rt<<1|1);
            return ans;
        }
    }S;
    struct num{
        int value;
        int position;
    }A[MAXN];
    struct queries{
        int l, r;
        int a, b;
        int num_greater_a;
        int num_less_b;
        int res;
        int id;
    }q[MAXN];
    bool cmp(num n1, num n2){
        return n1.value < n2.value;
    }
    bool cmp1(queries n1, queries n2){
        return n1.a > n2.a;
    }
    bool cmp2(queries n1, queries n2){
        return n1.b < n2.b;
    }
    bool cmpid(queries n1, queries n2){
        return n1.id < n2.id;
    }
    int main(){
        int t;
        scanf("%d", &t);
        for (int o = 1; o <= t; o ++){
            int n, m;
            scanf("%d %d", &n, &m);
            for (int i = 0; i < n; i ++){
                scanf("%d", &A[i].value);
                A[i].position = i + 1;
            }
            for (int i = 0; i < m; i ++){
                scanf("%d %d %d %d", &q[i].l, &q[i].r, &q[i].a, &q[i].b);
                q[i].id = i;
            }
            sort(A, A+n, cmp);
            sort(q, q+m, cmp1);
            int j = n - 1;
            S.build();
            for (int i = 0; i < m; i ++){
                while(j >= 0 && A[j].value >= q[i].a){
                    S.update(A[j].position, 1, 1, n, 1);
                    j --;
                }
                q[i].num_greater_a = S.query(q[i].l, q[i].r, 1, n, 1);
            }
            sort(q, q+m, cmp2);
            j = 0;
            S.build();
            for (int i = 0; i < m; i ++){
                while(j < n && A[j].value <= q[i].b){
                    S.update(A[j].position, 1, 1, n, 1);
                    j ++;
                }
                q[i].num_less_b = S.query(q[i].l, q[i].r, 1, n, 1);
                q[i].res = q[i].num_greater_a + q[i].num_less_b - (q[i].r - q[i].l + 1);
            }
            sort(q, q+m, cmpid);
            printf("Case #%d:
    ", o);
            for (int i = 0; i < m; i ++){
                printf("%d
    ", q[i].res);
            }
        }
        return 0;
    }
     
    /**************************************************************
        Problem: 2224
        User: AbandonZHANG
        Language: C++
        Result: Accepted
        Time:1052 ms
        Memory:4016 kb
    ****************************************************************/
    
  • 相关阅读:
    【Leetcode】【Easy】Remove Duplicates from Sorted List
    【Leetcode】【Easy】Pascal's Triangle II
    【Leetcode】【Easy】Pascal's Triangle
    【Leetcode】【Easy】Binary Tree Level Order Traversal II
    【Leetcode】【Easy】Binary Tree Level Order Traversal
    【Leetcode】【Easy】Maximum Depth of Binary Tree
    【Leetcode】【Easy】Minimum Depth of Binary Tree
    【Leetcode】【Easy】Balanced Binary Tree
    【Leetcode】【Easy】Symmetric Tree
    如何使用Action.Invoke()触发一个Storyboard
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4114251.html
Copyright © 2011-2022 走看看