HDU - 4417 Super Mario(分块+二分)

将给定区间分块,将每个块从小到大排序,二分查询每个块,

#include<bits/stdc++.h>

#define mem(a,b) memset(a,b,sizeof(a))
#define sc(x) scanf("%d",&(x))

using namespace std;

const int maxn=1e5+10;

int block,mub,l[maxn],r[maxn],belong[maxn];

int arr[maxn],n,m,tt[maxn];

void built()
{
    block=sqrt(n);
    mub=n/block;if(n%mub) mub++;
    for(int i=1;i<=mub;i++)
        l[i]=(i-1)*block+1,r[i]=i*block;
    r[mub]=n;
    for(int i=1;i<=n;i++)
        belong[i]=(i-1)/block+1;
    for(int i=1;i<=n;i++)
        sort(tt+l[belong[i]],tt+1+r[belong[i]]);
}

int query(int a,int b,int c)
{
    int ans=0;
    if(belong[a]==belong[b])
    {
        for(int i=a;i<=b;i++)
            if(arr[i]<=c) ans++;
    }
    else
    {
        for(int i=a;i<=r[belong[a]];i++)
            if(arr[i]<=c) ans++;
        for(int i=belong[a]+1;i<belong[b];i++)
            ans+=upper_bound(tt+l[i],tt+r[i]+1,c)-tt-l[i];
        for(int i=l[belong[b]];i<=b;i++)
            if(arr[i]<=c) ans++;
    }
    return ans;
}

int main(){
    int t;
    sc(t);
    for(int ii=1;ii<=t;ii++)
    {
        sc(n),sc(m);
        for(int i=1;i<=n;i++)
        {
            sc(arr[i]);
            tt[i]=arr[i];
        }
        built();
        printf("Case %d:\n",ii);
        while(m--)
        {
            int l,r,c;
            sc(l),sc(r),sc(c);
            l++,r++;
            printf("%d\n",query(l,r,c));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/minun/p/11266540.html

时间: 2024-11-08 22:44:59

HDU - 4417 Super Mario(分块+二分)的相关文章

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): 6077    Accepted Submission(s): 2645 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ab

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

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 (树状数组/线段树)

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 (线段树+动态数组)

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 a

【划分树+二分】HDU 4417 Super Mario

第一次 耍划分树.. . 模板是找第k小的 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include &l

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