hdu4417 树状数组(求指定区间比指定数小的数的个数)

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

Problem Description

Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss’s castle as a line (the length is n), on every
integer point i there is a brick on height hi. Now the question is how many bricks in [L, R] Mario can hit if the maximal height he can jump is H.

Input

The first line follows an integer T, the number of test data.

For each test data:

The first line contains two integers n, m (1 <= n <=10^5, 1 <= m <= 10^5), n is the length of the road, m is the number of queries.

Next line contains n integers, the height of each brick, the range is [0, 1000000000].

Next m lines, each line contains three integers L, R,H.( 0 <= L <= R < n 0 <= H <= 1000000000.)

Output

For each case, output "Case X: " (X is the case number starting from 1) followed by m lines, each line contains an integer. The ith integer is the number of bricks Mario can hit for the ith query.

Sample Input

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

Sample Output

Case 1:
4
0
0
3
1
2
0
1
5
1
/**
hdu4417  树状数组(求指定区间比指定数小的数的个数)
http://blog.csdn.net/wmn_wmn/article/details/8034181
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn=300005;

int C[maxn],ans[maxn];
int n,m;

int lowbit(int x)
{
    return x&(-x);
}

int sum(int x)
{
    int ret=0;
    while(x>0)
    {
        ret+=C[x];
        x-=lowbit(x);
    }
    return ret;
}

void add(int x,int d)
{
    while(x<=n)
    {
        C[x]+=d;
        x+=lowbit(x);
    }
}

struct node
{
    int id,num;
    bool operator < (const node &other) const
    {
        return num < other.num;
    }
}a[maxn];
struct note
{
    int l,r,id,value;
    bool operator < (const note &other)const
    {
        return value <other.value;
    }
}b[maxn];

int main()
{
    int T,tt=0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&a[i].num);
            a[i].id=i+1;
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].value);
            b[i].l++;
            b[i].r++;
            b[i].id=i+1;
        }
        sort(a,a+n);
        sort(b,b+m);
        memset(C,0,sizeof(C));
        int k=0;
        for(int i=0;i<m;i++)
        {
            while(k<n&&a[k].num<=b[i].value)
            {
                add(a[k].id,1);
                k++;
            }
            ans[b[i].id]=sum(b[i].r)-sum(b[i].l-1);
        }
        printf("Case %d:\n",++tt);
        for(int i=1;i<=m;i++)
        {
            printf("%d\n",ans[i]);
        }
    }
    return 0;
}
时间: 2024-12-15 04:39:05

hdu4417 树状数组(求指定区间比指定数小的数的个数)的相关文章

树状数组求区间最值

树状数组求区间最值 树状数组(Binary Index Tree)利用二进制的一些性质巧妙的划分区间,是一种编程,时间和空间上都十分理想的求区间和的算法,同样我们可以利用树状数组优美的区间划分方法来求一个序列的最值 约定以 num[]  表示原数组, 以 idx[] 表示索引数组, Lowbit(x)=x&(-x) 树状数组求和时通过构造数组 idx[] 使 idx[k]=sum(num[tk]), tk [k-Lowbit(k)+1,k], 使用同样的方法构造最值索引数组: 以最大值为例, 先

Day2:T4用树状数组求逆序对

T4: 用树状数组求逆序对 A[I]为前缀和 推导 (A[J]-A[I])/(J-I)>=M A[j]-A[I]>=M(J-I) A[J]-M*J>=A[I]-M*I B[J]>=B[I] 之后就是求逆序对的事情了 然后这里学一下用树状数组的方法 原理是:树状数组是用来求区间和的是吧 就是按权值的区间统计那么可以BIT维护...然后扫一遍 也就是计算有多少个逆序对 按权值的区间统计就是记录数的个数

poj 2299 Ultra-QuickSort(树状数组求逆序数+离散化)

题目链接:http://poj.org/problem?id=2299 Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in

poj2299(离散化+树状数组求逆序)

数据范围比较大,先用离散化将数据映射到可控的范围,然后应用树状数组求逆序求解. 总共有N个数,如何判断第i+1个数到最后一个数之间有多少个数小于第i个数呢?不妨假设有一个区间 [1,N],只需要判断区间[i+1,N]之间有多少个数小于第i个数.如果我们把总区间初始化为0,然后把第i个数之前出现过的数都在相应的区间把它的值定为1,那么问题就转换成了[i+1,N]值的总和.再仔细想一下,区间[1,i]的值+区间[i+1,N]的值=区间[1,N]的值(i已经标记为1),所以区间[i+1,N]值的总和等

ZOJ-2386 Ultra-QuickSort 【树状数组求逆序数+离散化】

Description In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input seque

POJ2985 The k-th Largest Group[树状数组求第k大值 并查集]

The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted: 2875 Description Newman likes playing with cats. He possesses lots of cats in his home. Because the number of cats is really huge, Newman wants to g

树状数组求逆序对

给定n个数,要求这些数构成的逆序对的个数.除了用归并排序来求逆序对个数,还可以使用树状数组来求解.树状数组求解的思路:开一个能大小为这些数的最大值的树状数组,并全部置0.从头到尾读入这些数,每读入一个数就更新树状数组,查看它前面比它小的已出现过的有多少个数sum,然后用当前位置减去该sum,就可以得到当前数导致的逆序对数了.把所有的加起来就是总的逆序对数.题目中的数都是独一无二的,这些数最大值不超过999999999,但n最大只是500000.如果采用上面的思想,必然会导致空间的巨大浪费,而且由

HDU 5249 离线树状数组求第k大+离散化

KPI Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1160    Accepted Submission(s): 488 Problem Description 你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度.数十亿的请求被推到一个大管道后同时服务从管头拉取请求.让我们来定义每个请求都有一个重要值.我的

树状数组求逆序数

poj 2299 树状数组求逆序数题目链接:http://poj.org/problem?id=2299 1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <stack> 8 #include <