HDU 4417 线段树离线&&主席树在线-程序员宅基地

技术标签: 数据结构_线段树  数据结构_树链剖分  数据结构_可持久化  ACM/ICPC_ BZOJ  数据结构_主席树  

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

解法1: 线段树/BIT离线
1,先把所有位置的高度都存下来,然后排序,注意保存下标;2,把所有询问存下来,然后按照询问的高度进行排序,同注意保存下标;3,对于排序后的每次询问的处理:由于每个位置的高度都已经存了下来并且进行了排序,所以可以按照顺序将每个点插入到线段树的对应位置(保存的下标),并更新 线段树,直到要插入的位置的高度大于这次询问的高度H;最后处理区间查询,由于刚才已经把小于等于该次查询高度的位置都已经插入到了线段树中,所以询问的 结果就是查询区间中被更新过的叶子节点的个数,也就是区间求和问题。当然换成BIT也完全一样

//156ms 4.9Mb
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
struct node{
    int h, pos;
    node(){}
    node(int h, int pos) : h(h), pos(pos){}
    bool operator < (const node &rhs) const{
        return h < rhs.h;
    }
}a[maxn];

struct Q{
    int l, r, h, id;
    Q(){}
    Q(int l, int r, int h, int id) : l(l), r(r), h(h), id(id){}
    bool operator < (const Q &rhs) const{
        return h < rhs.h;
    }
}q[maxn];

int ans[maxn];
namespace segmenttree{
    int sum[maxn*4];
    inline void init(){memset(sum, 0, sizeof(sum));}
    inline void pushup(int o){sum[o] = sum[o*2] + sum[o*2+1];}
    inline void update(int pos, int l, int r, int o){
        if(l == r){
            sum[o]++;
            return ;
        }
        int m = (l + r) / 2;
        if(pos <= m) update(pos, l, m, o*2);
        else update(pos, m + 1, r, o*2+1);
        pushup(o);
    }
    inline int query(int L, int R, int l, int r, int o){
        if(L <= l && r <= R) return sum[o];
        int m = (l + r) / 2;
        if(R <= m) return query(L, R, l, m, o*2);
        else if(L > m) return query(L, R, m + 1, r, o*2+1);
        else return query(L, m, l, m, o*2) + query(m + 1, R, m + 1, r, o*2+1);
    }
}
using namespace segmenttree;
int main(){
    int n, m, T, ks = 0;
    scanf("%d", &T);
    while(T--){
        printf("Case %d:\n", ++ks);
        init();
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i].h), a[i].pos = i;
        for(int i = 1; i <= m; i++){
            scanf("%d%d%d", &q[i].l, &q[i].r, &q[i].h); q[i].id = i;
        }
        sort(a + 1, a + n + 1);
        sort(q + 1, q + m + 1);
        int i, j;
        for(i = j = 1; i <= m; i++){
            int id = q[i].id, l = q[i].l, r = q[i].r;
            while(a[j].h <= q[i].h && j <= n){
                update(a[j++].pos, 1, n, 1);
            }
            ans[id] = query(l + 1, r + 1, 1, n, 1);
        }
        for(int k = 1; k <= m; k++){
            printf("%d\n", ans[k]);
        }
    }
    return 0;
}

解法2:在线主席树做法,我们知道主席数可以方便的维护区间第k大,那么我们可以在此基础上统计第i小的的数小于k的个数。

//156ms 11.1MB
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
const int maxm = 30*maxn;
int n, m, q, tot, a[maxn], b[maxn];
int getid(int x){
   return lower_bound(b + 1, b + m + 1, x) - b; }//下标从1开始
namespace chairmantree{
    int T[maxm], lson[maxm], rson[maxm], c[maxm];
    int build(int l, int r){
        int root = tot++;
        c[root] = 0;
        if(l != r){
            int mid = (l + r) / 2;
            lson[root] = build(l, mid);
            rson[root] = build(mid + 1, r);
        }
        return root;
    }
    int update(int root, int pos, int val){
        int newroot = tot++, tmp = newroot;
        c[newroot] = c[root] + val;
        int l = 1, r = m;
        while(l < r){
            int mid = (l + r) / 2;
            if(pos <= mid){
                lson[newroot] = tot++, rson[newroot] = rson[root];
                newroot = lson[newroot], root = lson[root], r = mid;
            }
            else{
                rson[newroot] = tot++, lson[newroot] = lson[root];
                newroot = rson[newroot], root = rson[root], l = mid + 1;
            }
            c[newroot] = c[root] + val;
        }
        return tmp;
    }
    int query(int L, int R, int k){
        int res = 0;
        int l = 1, r = m;
        while(l < r){
            int mid = (l + r) / 2;
            if(k <= mid){
                r = mid;
                L = lson[L];
                R = lson[R];
            }
            else{
                l = mid + 1;
                res += c[lson[R]] - c[lson[L]];
                L = rson[L];
                R = rson[R];
            }
        }
        return res + (k < l ? 0 : c[R] - c[L]);
    }
}
using namespace chairmantree;

int main(){
    int TT, ks = 0;
    scanf("%d", &TT);
    while(TT--){
        printf("Case %d:\n", ++ks);
        scanf("%d%d", &n, &q);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for(int i = 1; i <= n; i++) b[i] = a[i];
        sort(b + 1, b + n + 1);
        m = unique(b + 1, b + n + 1) - b - 1;
        T[0] = build(1, m);
        for(int i = 1; i <= n; i++) T[i] = update(T[i-1], getid(a[i]), 1);
        while(q--){
            int l, r, h;
            scanf("%d%d%d", &l, &r, &h);
            h = upper_bound(b+1, b+m+1, h) - b - 1;//有重复元素,所以要找upper_bound
            printf("%d\n", query(T[l], T[r+1], h));
        }
    }
    return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/just_sort/article/details/58154832

智能推荐

详解冬奥冠军背后的AI黑科技-程序员宅基地

文章浏览阅读3.6k次。用人工智能普惠体育发展。

form表单提交的几种方式_提交表单-程序员宅基地

文章浏览阅读10w+次,点赞92次,收藏495次。表单提交方式一:直接利用form表单提交html页面代码:<!DOCTYPE html><html><head><meta charset="UTF-8" /><title>Insert title here</title></head><body><form action="h..._提交表单

Unity Spine SkeletonGraphic 动画重复播放 过度残影透明渐变Bug 解决方案_unity skeletongraphic-程序员宅基地

文章浏览阅读5.1k次。Unity Spine SkeletonGraphic 重复播放 过度残影Bug 解决方案不推荐使用SetToSetupPose和Setup Pose相关,代码直接贴上/// <summary>/// Spine播放设置/// </summary>/// <param name="trackIndex">填写0</param>/// <param name="animationName">动画名</param>/// &l_unity skeletongraphic

高斯分布3——边缘概率与条件概率_高斯分布的条件概率-程序员宅基地

文章浏览阅读3.5k次。一、推导过程:二、结果:边缘分布x1,x2 各自依然服从 μi,写反差矩阵 Σii 的多元高斯分布;条件概率分布给定 xj 求 xi 的分布:μi|j=μi+ΣijΣ−1jj(xj−μj)Σi|j=Σjj−ΣTijΣ−1iiΣij..._高斯分布的条件概率

Ratelimitcache: Python缓存库,支持速率限制-程序员宅基地

文章浏览阅读339次,点赞8次,收藏8次。Ratelimitcache: Python缓存库,支持速率限制项目链接: https://gitcode.com/simonw/ratelimitcache?utm_source=artical_gitcode如果你正在寻找一个Python缓存库,并且希望对缓存操作进行速率限制,那么Ratelimitcache可能是你的理想选择。什么是Ratelimitcache?Ratelimitca..._python ratelimit基于什么

【爬虫】Xpath和CSS信息提取的方法异同点_xpath 获取css-程序员宅基地

文章浏览阅读2.3k次,点赞2次,收藏8次。Xpath和CSS信息提取的方法异同点_xpath 获取css

随便推点

基于OFDM+64QAM系统的载波同步matlab仿真,输出误码率,星座图,鉴相器,锁相环频率响应以及NCO等-程序员宅基地

文章浏览阅读454次。正交频分复用(OFDM)是一种在现代通信系统中广泛使用的调制技术,它具有高效的频谱利用和抗多径衰落等特点。64QAM(64-ary Quadrature Amplitude Modulation)是一种调制方式,可以在每个符号中传输更多的位信息。在OFDM系统中,保持载波同步对确保数据传输的可靠性至关重要。_基于ofdm+64qam系统的载波同步matlab仿真,

Springboot毕设项目超市商品销售管理系统37x2w(java+VUE+Mybatis+Maven+Mysql)_vue+springboot+mybatis商品管理系统-程序员宅基地

文章浏览阅读67次。Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。若包含,则为maven项目,否则为非maven项目。Springboot毕设项目超市商品销售管理系统37x2w(java+VUE+Mybatis+Maven+Mysql)Springboot + mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。其他版本理论上也可以。_vue+springboot+mybatis商品管理系统

关掉\禁用win7自动配置ipv4地址的方法 默认网关自动消失的解决办法_禁止修改网关命令-程序员宅基地

文章浏览阅读3w次,点赞2次,收藏4次。转载自: http://blog.csdn.net/zouqin369/article/details/6913692 今天去公司设置好IP后,无论怎么样都上不了internet,再次打开本地后发现默认网关自动消失,cmd下输入ipconfig后的现象如下: 物理地址. . . . . . . . . . . . . : 00-22-64-55-76-8F DHCP 已启用_禁止修改网关命令

Extjs4.2 window加载HTML,父子页面html传参_extjs中打开网页怎么传参-程序员宅基地

文章浏览阅读482次。Extjs的窗口是可以加载自己的HTML的,但这样两个页面就相当独立了,传参是个问题 ,网上也没有很好的解答清楚,猫猫今天就说清楚这个模式的传参要点。_extjs中打开网页怎么传参

计算机网络复习——Ch3点到点数据链路层_hdlc go-back-n-程序员宅基地

文章浏览阅读1.2k次。Ch3点到点数据链路层知识点1. 点到点数据链路层要解决的主要问题2. 常见的帧管理(帧定界)方法3. CRC的计算4. 流量控制的基本原理5. 常见错误及其处理机制6. 滑动窗口的概念、形式及工作原理7. ARQ(Automatic Repeat reQuest)协议工作原理:8. 连续ARQ(Go-back-N ARQ)工作原理(特别注意累计确认):9. 选择重传ARQ工作原理10. 了解(高..._hdlc go-back-n

推荐文章

热门文章

相关标签