题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 , 线段树(或树状数组) + 离线处理

  最近看了几道线段树的题都是需要离线处理数据的,正好这块比较手生,就练练了。


   这道题主要的地方就是离线处理数据,具体想法:

  ① 先把所有位置的高度都存下来,然后排序,注意保存下标;

  ② 把所有询问存下来,然后按照询问的高度进行排序,同注意保存下标;

  ③ 对于排序后的每次询问的处理:由于每个位置的高度都已经存了下来并且进行了排序,所以可以按照顺序将每个点插入到线段树的对应位置(保存的下标),并更新线段树,直到要插入的位置的高度大于这次询问的高度H;最后处理区间查询,由于刚才已经把小于等于该次查询高度的位置都已经插入到了线段树中,所以询问的结果就是查询区间中被更新过的叶子节点的个数,也就是区间求和问题。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = ;
const int maxn = + ;
const int N = ;
struct Node { //每个节点的信息
int h , pos;
bool operator < (const Node tmp) const {
return h < tmp.h;
}
} a[maxn];
struct Section { //每次查询的区间信息
int L , R , H;
int index;
bool operator < (const Section tmp) const {
return H < tmp.H;
}
} s[maxn];
int cnt[maxn << ] , ans[maxn];
void PushUp(int rt)
{
cnt[rt] = cnt[rt << ] + cnt[rt << | ];
}
void build()
{
memset(cnt , , sizeof(cnt));
}
void update(int p , int l , int r , int rt)
{
if(l == r) {
cnt[rt]++;
return;
}
int m = (l + r) >> ;
if(p > m) //找到更新点的位置
update(p , rson);
else
update(p , lson);
PushUp(rt);
}
int query(int L , int R , int l , int r , int rt)
{
if(L <= l && R >= r) {
return cnt[rt];
}
int m = (l + r) >> ;
if(L > m)
return query(L , R , rson);
else if(R <= m)
return query(L , R , lson);
else
return query(L , R , lson) + query(L , R , rson);
}
int main()
{
int T , i , j , n , m;
cin >> T;
for(int k = ; k <= T ; k++)
{
build();
printf("Case %d:\n" , k);
scanf("%d %d" , &n , &m);
for(i = ; i <= n ; i++) {
scanf("%d" , &a[i].h);
a[i].pos = i;
}
for(i = ; i <= m ; i++) {
scanf("%d %d %d" , &s[i].L , &s[i].R , &s[i].H);
s[i].index = i;
}
sort(a + , a + n + );
sort(s + , s + m + );
for(i = j = ; i <= m ; i++) { //这里就是上面的③
while(a[j].h <= s[i].H && j <= n) {
update(a[j++].pos , , n , );
}
ans[s[i].index] = query(s[i].L + , s[i].R + , , n , );
}
for(i = ; i <= m ; i++)
printf("%d\n" , ans[i]);
}
return ;
}

  此题还可以用划分树来做,并且特别快,可惜我没学~

HDU4417 线段树 + 离线处理的更多相关文章

  1. 线段树+离线 hdu5654 xiaoxin and his watermelon candy

    传送门:点击打开链接 题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的.如今告诉你序列.然后Q次询问.每次询问一个区间[l,r],问区间里有多少个三元组满足 ...

  2. 牛客练习赛53 E-老瞎眼pk小鲜肉(思维+线段树+离线)

    前言 听说是线段树离线查询?? 做题做着做着慢慢对离线操作有点感觉了,不过也还没参透,等再做些题目再来讨论离线.在线操作. 这题赛后看代码发现有人用的树状数组,$tql$.当然能用树状数组写的线段树也 ...

  3. HDU3874 线段树 + 离线处理

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3874 , 线段树(或树状数组) + 离线处理 下午做了第一道离线处理的题目(HDU4417),多少有点 ...

  4. HDU 4638-Group(线段树+离线处理)

    题意: 给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的) 分析: 我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号, ...

  5. HDU 4630-No Pain No Game(线段树+离线处理)

    题意: 给你n个数的序列a,q个询问,每个询问给l,r,求在下标i在[l,r]的区间任意两个数的最大公约数中的最大值 分析: 有了hdu3333经验,我们从左向右扫序列,如果当前数的约数在前面出现过, ...

  6. HDU 4288 Coder 【线段树+离线处理+离散化】

    题意略. 离线处理,离散化.然后就是简单的线段树了.需要根据mod 5的值来维护.具体看代码了. /* 线段树+离散化+离线处理 */ #include <cstdio> #include ...

  7. SPOJ--K-query (线段树离线) 离线操作解决一些问题

    K-query Given a sequence of n numbers a1, a2, ..., an and a number of k- queries. A k-query is a tri ...

  8. lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增

    https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...

  9. 51nod 1463 找朋友(线段树+离线处理)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1463 题意: 思路: 好题! 先对所有查询进行离线处理,按照右区间排序, ...

随机推荐

  1. 【leetcode 76. 最小覆盖子串】解题报告

    思路:滑动窗口思想 方法一:滑动窗口 string minWindow(string s, string t) { // 1.tdict记录T中每个字母与字母个数 // 2.维护一个滑动窗口字母的计数 ...

  2. 洛谷P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper

    P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper 题目描述 A little known fact about Bessie and friends is ...

  3. Gradle用户使用指南

    转载请事先沟通,未经允许,谢绝转载. 1. 新工具介绍(Introduction) 能够复用代码和资源能够构建几种不同版本参数的应用能够配置.扩展.自定义构建过程1.1 为什么选择Gradle(Why ...

  4. 打开powerDesigner时,创建table对应的自动生成sql语句没有注释

    在创建pdm时由于需要在name列填写的是以后要在表中创建的注释信息,comment中则写的说明信息字数比较多.默认情况下在生成建表sql时不能将name生成注释信息,进行如下设置可以讲name生成注 ...

  5. CF24D Broken robot 后效性DP

    这题咕了好久..... 设$f[i][j]$表示从$(i,j)$到最后一行的期望步数: 则有 $ f[i][1]=\frac{1}{3}(f[i][1]+f[i][2]+f[i+1][1])+1$ $ ...

  6. 树的计数 Prufer序列+Cayley公式

    先安利一发.让我秒懂.. 第一次讲这个是在寒假...然而当时秦神太巨了导致我这个蒟蒻自闭+颓废...早就忘了这个东西了... 结果今天老师留的题中有两道这种的:Luogu P4981 P4430 然后 ...

  7. 弹层组件文档 - layui.layer

    http://www.layui.com/doc/modules/layer.html

  8. 在CMD下运用管理员权限

    方法一:鼠标右键 这个方法比较比较普通,点开开始找到cmd,右击鼠标“以管理员身份运行(A)”这样调用就是管理员的权限: 方法二:快捷模式 在点开win+R后,选择“以管理员身份运行”,然后确定:可以 ...

  9. 一个简单的CI分页类

    [php] view plaincopy <span style="font-size:16px;">/** * * 关于 页码有效性的判断需要加在 控制器中判断,即当 ...

  10. 汇编语言版本的HelloWorld

    平台 macOS 工具 nasm clang 文件 main.asm extern _printf ; 这里调用系统的一个系统调用函数, _printf, 使用extern告诉链接器该label在其他 ...