hdu 4417 Super Mario (线段树+动态数组)

Super Mario

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2685    Accepted Submission(s): 1306

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
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 100050;

struct node
{
    int l,r,len;
    int *sub;
} a[maxn*4];
int n,m,b[maxn];

void build(int l,int r,int k)
{
    a[k].l=l,a[k].r=r;
    a[k].sub = new int[r-l+3];
    int cnt=0;
    for(int i=l; i<=r; i++) a[k].sub[cnt++]=b[i];
    a[k].len=cnt;
    sort(a[k].sub,a[k].sub+cnt);
    if(l!=r)
    {
        int mid=(l+r)>>1;
        build(l,mid,2*k);
        build(mid+1,r,2*k+1);
    }
}

int query(int l,int r,int h,int k)
{
    if(a[k].l==l && a[k].r==r)
    {
         int num=upper_bound(a[k].sub,a[k].sub+a[k].len,h)-a[k].sub;
         return num;
    }
    else
    {
        int mid=(a[k].l+a[k].r)>>1;
        if(r<=mid)  return query(l,r,h,2*k);
        else if(l>mid)   return query(l,r,h,2*k+1);
        else  return query(l,mid,h,2*k)+query(mid+1,r,h,2*k+1);

    }
}

void Delete(int l,int r,int k)
{
    delete[] a[k].sub;
    if(l!=r)
    {
        int mid=(l+r)>>1;
        Delete(l,mid,2*k);
        Delete(mid+1,r,2*k+1);
    }
}

int main()
{
    int T,x,y,h;
    scanf("%d",&T);
    for(int co=1; co<=T; co++)
    {
        scanf("%d %d",&n,&m);
        for(int i=1; i<=n; i++)  scanf("%d",&b[i]);
        build(1,n,1);
        printf("Case %d:\n",co);
        for(int i=1; i<=m; i++)
        {
            scanf("%d %d %d",&x,&y,&h);
            printf("%d\n",query(x+1,y+1,h,1));
        }
        Delete(1,n,1);
    }
    return 0;
}
时间: 2024-08-18 22:55:48

hdu 4417 Super Mario (线段树+动态数组)的相关文章

hdu 4417 Super Mario(离线树状数组|划分树)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2584    Accepted Submission(s): 1252 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping a

hdu 4417 Super Mario (线段树+离线)

题意: n个砖块,第i个砖块的高度是hi. m个query,每个query的格式:L R H (输出[L,R]中有多少个hi小于等于H[即玛里奥能跳过多少块砖]) 数据范围: 1 <= n <=10^5, 1 <= m <= 10^5 Next line contains n integers, the height of each brick, the range is [0, 1000000000]. ( 0 <= L <= R < n 0 <= H &

HDU 4417 Super Mario 划分树/树状数组

题目大意:给定一个序列,求区间内小于等于某数的元素数量 首先区间排名一看就是划分树 不过和第k小不一样 我们需要做一些处理 第一种处理方式是二分答案 然后转换成区间第k小 好方法我喜欢 但是这里说的不是这种方法 首先建树,然后对于每个询问,我们讨论k与a[mid]的关系 若k<a[mid],则右子树一定没有小于等于k的数,我们进入左子树查找 若k>=a[mid],则左子树内一定所有数都小于等于k,于是我们将查询区间中进入左子树的元素的数量记入ans,然后查找右区间 递归退出条件是查询区间为空或

HDU 4417 Super Mario(划分树问题求不大于k的数有多少)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3625    Accepted Submission(s): 1660 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability

HDU 4417 Super Mario 主席树查询区间小于某个值的个数

#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<vector> #define LL long long #define rep(i,j,k) for(int i=j;i<=k;i++) #define per(i,j,k) for(int i=j;i>=k;i--) #define pb push_back #d

HDU 4417 Super Mario ( 超级马里奥 + 主席树 + 线段树/树状数组离线处理 + 划分树 )

HDU 4417 - Super Mario ( 主席树 + 线段树/树状数组离线处理 + 划分树 ) 这道题有很多种做法,我先学习的是主席树.后面陆续补上线段树离线和划分树 题目大意就是给定一个区间给定一个数列,每次要求你查询区间[L,R]内不超过K的数的数量 主席树做法: 最基本的是静态第k大,这里是求静态的 <= K,差不多,在Query操作里面需要修改修改 先建立size棵主席树,然后询问的时候统计的是 第R棵主席树中[1,K]的数量 - 第L-1棵主席树中[1,K]的数量 注意这里下标

HDU 4417 Super Mario (树状数组/线段树)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble agai

HDU 4417 Super Mario(离线线段树or树状数组)

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 l

(树状数组+离线查询)HDU 4417 - Super Mario

题意: 给定一个数列,最多10万次查询l到r不超过h的数字的个数. 分析: 唉,太菜啦. 在线做法应该比较明显,区间维护平衡树,用线段树套平衡树,或者分块套平衡树,应该都能A,但是没试过,只是BB,如有错误欢迎指正. 其实最方便的做法离线做法,太巧妙啦. 把数列按升序排列,把所有查询按h升序排列. 每次查询把比h的小的位置标记为1,查询用bit的sum(r)-sum(l-1)即可 因为都是单调的,所以很方便. 其实很多没有修改的区间问题都可以转化成离线问题. 甚至于一些带修改的题都可以离线. 这