【hdu4417】Super Mario——主席树

题目链接

题目大意为给定一个长度为n的区间,同时给出m个询问,每次询问在区间[l,r]中有多少个数小于或等于k。

同样考虑用主席树来维护,每次只需要找到序列b中第一个等于k的数,那么要求的数必定在b[1]~b[upper_bound(k)]这个范围内,接下来就像线段树统计区间个数那样,若完全包含则直接加上e[rr].sum-e[ll].sum,否则就分两边递归统计。而建树什么的就直接套模板即可。

还要注意一点,原题的区间默认从0开始,因此若像我一样写了区间从1开始的记得在query之前将l和r加上1。

最最最最后一点,hdu的老规矩,要注意处理好多组数据。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=1e5+5;
using namespace std;
struct point{
    int rt,sum,ls,rs;
}e[N*20];
int a[N],b[N],tot,n,m,sz,x,y;
void build(int &rt,int le,int ri)
{
    tot++;rt=tot;
    e[rt].sum=0;
    if(le==ri)return ;
    int mid=(le+ri)>>1;
    build(e[rt].ls,le,mid);
    build(e[rt].rs,mid+1,ri);
}
void up(int &rt,int l,int r,int last,int p)
{
    rt=++tot;
    e[rt].ls=e[last].ls;e[rt].rs=e[last].rs;
    e[rt].sum=e[last].sum+1;
    if(l==r)return;
    int mid=(l+r)>>1;
    if(p<=mid)up(e[rt].ls,l,mid,e[last].ls,p);
    else up(e[rt].rs,mid+1,r,e[last].rs,p);
}
int query(int ll,int rr,int l,int r)
{
    if(x>y)return 0;
    if(x<=l&&y>=r)return e[rr].sum-e[ll].sum;
    int mid=(l+r)>>1;
    int ret=0;
    if(x<=mid)ret+=query(e[ll].ls,e[rr].ls,l,mid);
    if(y>mid)ret+=query(e[ll].rs,e[rr].rs,mid+1,r);
    return ret;
}
void find()
{
    int ll,rr,kk;
    scanf("%d %d %d",&ll,&rr,&kk);
    ll++;rr++;
    x=1;y=upper_bound(b+1,b+1+sz,kk)-(b+1);
    int an=query(e[ll-1].rt,e[rr].rt,1,sz);
    printf("%d\n",an);
}
int main()
{
    int T,ss=1;
    scanf("%d",&T);
    while(T--)
    {
        tot=0;
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        sz=unique(b+1,b+n+1)-(b+1);
        build(e[0].rt,1,sz);
        for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+1+sz,a[i])-b;
        for(int i=1;i<=n;i++)up(e[i].rt,1,sz,e[i-1].rt,a[i]);
        printf("Case %d:\n",ss);ss++;
        while(m--)find();
    }
    return 0;
}

hdu4417

时间: 2024-08-13 14:54:21

【hdu4417】Super Mario——主席树的相关文章

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(树状数组 + 划分树)

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

hdu4417 Super Mario 树状数组离线/划分树

http://acm.hdu.edu.cn/showproblem.php?pid=4417 Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2720    Accepted Submission(s): 1322 Problem Description Mario is world-famous plumber

hdu_4417_Super Mario(主席树)

题目链接:hdu_4417_Super Mario 题意: 给你n个树,有m个询问,每个询问有一个区间和一个k,问你这个区间内不大于k的数有多少个. 题解: 考虑用主席树的话就比较裸,当然也可以用其他的写 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 using namespace std; 4 5 const int N=1e5+7; 6 int a[N],t,n,m,hsh[N],hsh_le

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(划分树问题求不大于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

HDU4417 Super Mario(主席树)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4417 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

ACM学习历程—HDU4417 Super Mario(树状数组 &amp;&amp; 离线)

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 (

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

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