hdu 4417 Super Mario(主席树)

题意:给你一些数,有多次询问,问你在l,r区间内小于k的数有多少个

思路:主席树大发好,虽然树状数组和线段树离线也可以做

代码:

#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define zero(a) fabs(a)<eps
#define max( x, y )  ( ((x) > (y)) ? (x) : (y) )
#define min( x, y )  ( ((x) < (y)) ? (x) : (y) )
#define lowbit(x) (x&(-x))
#define debug(a) cerr<<#a<<"=="<<a<<endl
typedef long long LL;
const double pi=acos(-1.0);
const double eps=1e-8;
const int inf=0x3f3f3f3f;
const LL linf=0x3f3f3f3f3f3f3f3f;
using namespace std;

const int maxn=100007;
int n,m,a[maxn],root[maxn],cnt,x,y,k;
struct node
{
    int l,r,sum;
}T[maxn*40];
vector<int>v;
int getid(int x)
{
    return lower_bound(v.begin(),v.end(),x)-v.begin();
}
void update(int l,int r,int &x,int y,int pos)
{
    T[++cnt]=T[y],T[cnt].sum++,x=cnt;
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(pos<=mid)update(l,mid,T[x].l,T[y].l,pos);
    else update(mid+1,r,T[x].r,T[y].r,pos);
}

int query(int l,int r,int x,int y,int L,int R)
{
    if(L>R) return 0;
    if(L<=l && r<=R){
        return T[y].sum-T[x].sum;
    }
    int mid=(l+r)>>1,ans=0;
    if(L<=mid) ans+=query(l,mid,T[x].l,T[y].l,L,R);
    if(R>mid) ans+=query(mid+1,r,T[x].r,T[y].r,L,R);
    return ans;
}
int main()
{
    int tt;
    scanf("%d",&tt);
    int cas=1;
    while(tt--){
        scanf("%d%d",&n,&m);
        v.clear();
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            v.push_back(a[i]);
        }
        sort(v.begin(),v.end());
        v.erase(unique(v.begin(),v.end()),v.end());
        for(int i=1;i<=n;i++){
            update(0,v.size()-1,root[i],root[i-1],getid(a[i]));
        }
        printf("Case %d:\n",cas++);
        int t1,t2,t3;
        while(m--){
            scanf("%d%d%d",&t1,&t2,&t3);
            int pos=upper_bound(v.begin(),v.end(),t3)-v.begin()-1;
            printf("%d\n",query(0,v.size()-1,root[t1],root[t2+1],0,pos));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lalalatianlalu/p/8855114.html

时间: 2024-11-10 16:19:12

hdu 4417 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) 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

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

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

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 ( 超级马里奥 + 主席树 + 线段树/树状数组离线处理 + 划分树 )

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) Total Submission(s): 5101    Accepted Submission(s): 2339 Problem Description Mario is world-famous plumber. His “burly” figure and amazing jumping abilit

hdu 4417 Super Mario (主席树)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用分块写过类似的,不过为了练习下主席树,这里用主席树写了下.思路很简单 离线离散化处理下,每次插入一个数num时,在主席树上下标num+1,这样每次询问[l,r]中有多少个小于k的数的时候,我们只要找下标[1,k]的区间第R次修改后的总和减去第L-1次修改后的总值就可以得到了 实现代码: #inclu

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