zoukankan      html  css  js  c++  java
  • SDUT 2610 Boring Counting(离散化+主席树区间内的区间求和)

    Boring Counting

    Time Limit: 3000MS Memory Limit: 65536KB

    Problem Description

        In this problem you are given a number sequence P consisting of N integer and Pi is the ith element in the sequence. Now you task is to answer a list of queries, for each query, please tell us among [L, R], how many Pi is not less than A and not greater than B( L<= i <= R). In other words, your task is to count the number of Pi (L <= i <= R,  A <= Pi <= B).

    Input

         In the first line there is an integer T (1 < T <= 50), indicates the number of test cases. 
         For each case, the first line contains two numbers N and M (1 <= N, M <= 50000), the size of sequence P, the number of queries. The second line contains N numbers Pi(1 <= Pi <= 10^9), the number sequence P. Then there are M lines, each line contains four number L, R, A, B(1 <= L, R <= n, 1 <= A, B <= 10^9)

    Output

        For each case, at first output a line ‘Case #c:’, c is the case number start from 1. Then for each query output a line contains the answer.

    Example Input

    1
    13 5
    6 9 5 2 3 6 8 7 3 2 5 1 4
    1 13 1 10
    1 13 3 6
    3 6 3 6
    2 8 2 8
    1 9 1 9

    Example Output

    Case #1:
    13
    7
    3
    6
    9

    题目链接:SDUT 2610

    裸的主席树区间查询,但是要注意一下就是离散化之后若输入的值域中有小于最小值的,即计算原位置后会出现0,因此建树若范围是1~pos.size()的话就会超时,建议改为0~pos.size();

    若有大于最大值的,则离散化之后会自动替换被为最大值,然而此题这样做当然是错的,因此a不用找接近值代替而要把上限b要找接近值代替,这样一来若b大于最大值,则代替没有关系,若b等于a且均大于最大值,则会出现b比a小的情况,特判一下输出0,然后若b比最小值都要小,则直接让B等于0,也特判为输出0。

    调试了一会儿终于过了,= =划分树什么的这题肯定木有这个主席树这么好用啦……再说数据结构还没学到这玩意儿……也就会个主席树了……。

    最后把这组数据调通就过了……

    1
    13 8
    1 2 3 4 5 6 7 8 9 10 11 12 13
    1 13 14 14

    答案应该是0,如果答案是1的话估计就是离散化位置计算出了点问题

    代码:

    #include <stdio.h>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <sstream>
    #include <cstring>
    #include <bitset>
    #include <string>
    #include <deque>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <set>
    #include <map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    typedef pair<int,int> pii;
    typedef long long LL;
    const double PI=acos(-1.0);
    const int N=50010;
    struct seg
    {
        int lson,rson;
        int cnt;
    };
    seg T[N*20];
    int root[N],tot;
    pii arr[N];
    vector<int>pos;
    void update(int &cur,int ori,int l,int r,int pos)
    {
        cur=++tot;
        T[cur]=T[ori];
        ++T[cur].cnt;
        if(l==r)
            return ;
        int mid=MID(l,r);
        if(pos<=mid)
            update(T[cur].lson,T[ori].lson,l,mid,pos);
        else
            update(T[cur].rson,T[ori].rson,mid+1,r,pos);
    }
    int query(int S,int E,int l,int r,int L,int R)
    {
        if(L<=l&&r<=R)
            return T[E].cnt-T[S].cnt;
        else
        {
            int mid=MID(l,r);
            if(R<=mid)
                return query(T[S].lson,T[E].lson,l,mid,L,R);
            else if(L>mid)
                return query(T[S].rson,T[E].rson,mid+1,r,L,R);
            else
                return query(T[S].lson,T[E].lson,l,mid,L,mid)+query(T[S].rson,T[E].rson,mid+1,r,mid+1,R);
        }
    }
    void init()
    {
        CLR(root,0);
        tot=0;
        T[0].cnt=T[0].lson=T[0].rson=0;
        pos.clear();
    }
    int main(void)
    {
        int tcase,n,m,l,r,a,b,i;
        scanf("%d",&tcase);
        for (int q=1; q<=tcase; ++q)
        {
            init();
            scanf("%d%d",&n,&m);
            for (i=1; i<=n; ++i)
            {
                scanf("%d",&arr[i].first);
                pos.push_back(arr[i].first);
            }
            sort(pos.begin(),pos.end());
            pos.erase(unique(pos.begin(),pos.end()),pos.end());
            int SZ=pos.size();
            for (i=1; i<=n; ++i)
            {
                arr[i].second=lower_bound(pos.begin(),pos.end(),arr[i].first)-pos.begin()+1;
                update(root[i],root[i-1],0,SZ,arr[i].second);
            }
            printf("Case #%d:
    ",q);
            for (i=0; i<m; ++i)
            {
                scanf("%d%d%d%d",&l,&r,&a,&b);
                int A,B;
                A=lower_bound(pos.begin(),pos.end(),a)-pos.begin()+1;
                B=lower_bound(pos.begin(),pos.end(),b)-pos.begin()+1;
                if(pos[B-1]!=b)//上限B的位置要特别计算一下
                    --B;
                if(!B||A>B)//特判
                    puts("0");
                else
                    printf("%d
    ",query(root[l-1],root[r],0,SZ,A,B));
            }
        }
        return 0;
    }
  • 相关阅读:
    完结篇《产品在路上》
    产品经理的七个层次
    互联网产品的交互设计
    互联网产品的用户体验
    用户体验设计 UED (下)
    用户体验设计 UED (上)
    【100Days of 100 line Code】1 day
    leetcode 392.判断子序列(Java 贪心)
    leetcode 605.种花问题(java 贪心)
    leetcode 122.买卖股票的最佳时机||(Java 贪心)
  • 原文地址:https://www.cnblogs.com/Blackops/p/5939104.html
Copyright © 2011-2022 走看看