Super Mario

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5560    Accepted Submission(s): 2532

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
 

http://acm.hdu.edu.cn/showproblem.php?pid=4417

一开始的时候,很难想,和以前的树状数组不同,但是有一点是固定的。

既然要是区间里的个数,那么就肯定离不开L, R

开始的时候还以为学以前的区间统计不同数字的个数一样。对R排序,然后每个压进树状数组。

但是这样不行,查询元素的变得十分麻烦。

比如1、5、7、3

我把这些元素都压进去了,然后查询[3, 4]小于等于6的个数,就会很麻烦。

既要减去[1, 2]的,也有些数字比6大。、

主要是没用上L和R。这两个是必须用的,都是getsum(R) - getsum(L - 1)进而得到答案。都是这个套路。

那么就是看看[L, R]这一段连续的区间,有多少个数是小于等于val的。那么我们先保证,现在每一个压进树状

数组的元素都是<=val的,这个可以保证,然后更新数字的时候,就是跟新他们的位置,所以这时候查询就直接来就行了。

这一招保证每一次query的时候元素都是合法的技巧,以前用过一次,可惜忘记了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e5 + ;
int c[maxn];
int n, m;
int lowbit(int x) {
return x & (-x);
}
void UpDate(int pos, int val) {
while (pos <= n) {
c[pos] += val;
pos += lowbit(pos);
}
}
int getsum(int pos) {
int ans = ;
assert(pos >= );
while (pos) {
ans += c[pos];
pos -= lowbit(pos);
}
return ans;
}
struct haha {
int val, id;
bool operator < (const struct haha & rhs) const {
return val < rhs.val;
}
}a[maxn];
struct node {
int L, R, id, val;
bool operator < (const struct node & rhs) const {
return val < rhs.val;
}
}query[maxn];
int ans[maxn];
void init() {
memset(c, , sizeof c);
}
void work() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i].val);
a[i].id = i;
}
sort(a + , a + + n);
for (int i = ; i <= m; ++i) {
scanf("%d%d%d", &query[i].L, &query[i].R, &query[i].val);
query[i].L++;
query[i].R++;
query[i].id = i;
}
sort(query + , query + + m);
int now = ;
for (int i = ; i <= m; ++i) {
while (now <= n && query[i].val >= a[now].val) {
UpDate(a[now].id, );
now++;
}
ans[query[i].id] = getsum(query[i].R) - getsum(query[i].L - );
}
static int f = ;
printf("Case %d:\n", ++f);
for (int i = ; i <= m; ++i) {
printf("%d\n", ans[i]);
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) {
init();
work();
}
return ;
}

我这个线段树不是其他线段树。

我的每个节点都保存了所有区间的数字。并且排序

就是把归并排序的过程记录下来了。

然后对于每一个个查询。

1、如果区间全部包含了,那么直接二分查找即可。

2、递归搜索。

注意pushUp的时候,要先vector<>.resize();

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#define root 1, n, 1
#define lson L, mid, cur << 1
#define rson mid + 1, R, cur << 1 | 1
const int maxn = 1e5 + ;
vector<int>seg[maxn << ];
int a[maxn];
int n, m;
void pushUp(int cur) {
// cout << "ff" << endl;
// cout << seg[cur << 1].size() << endl;
merge(seg[cur << ].begin(), seg[cur << ].end(), seg[cur << | ].begin(), seg[cur << | ].end(), seg[cur].begin());
}
void build(int L, int R, int cur) {
if (L == R) {
seg[cur].clear();
seg[cur].push_back(a[L]);
return;
}
int mid = (L + R) >> ;
build(lson);
build(rson);
seg[cur].resize(R - L + );
pushUp(cur);
}
int query(int be, int en, int val, int L, int R, int cur) {
if (L >= be && R <= en) {
if (val >= seg[cur].back()) {
return R - L + ;
} else {
int pos = upper_bound(seg[cur].begin(), seg[cur].end(), val) - seg[cur].begin();
return pos;
}
}
int mid = (L + R) >> ;
int lans = , rans = ;
if (mid >= be) {
lans = query(be, en, val, lson);
}
if (mid < en) {
rans = query(be, en, val, rson);
}
return lans + rans;
}
void upDate(int pos, int val, int L, int R, int cur) {
if (L == R) {
if (pos == L) {
seg[cur].clear();
seg[cur].push_back(val);
}
return;
}
int mid = (L + R) >> ;
if (pos <= mid) upDate(pos, val, lson);
else upDate(pos, val, rson);
pushUp(cur);
}
void work() {
scanf("%d%d", &n, &m);
// cout << n << " " << m << endl;
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
}
build(root);
// for (int i = 0; i < seg[1].size(); ++i) {
// cout << seg[1][i] << " ";
// }
// cout << endl;
// cout << "ff" << endl;
static int f = ;
printf("Case %d:\n", ++f);
while (m--) {
int be, en, x;
scanf("%d%d%d", &be, &en, &x);
be++;
en++;
int res = query(be, en, x, root);
printf("%d\n", res);
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return ;
}

Super Mario 树状数组离线 || 线段树的更多相关文章

  1. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  2. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  3. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

  4. POJ 1195 Mobile phones (二维树状数组或线段树)

    偶然发现这题还没A掉............速速解决了............. 树状数组和线段树比较下,线段树是在是太冗余了,以后能用树状数组还是尽量用......... #include < ...

  5. 【BZOJ3196】二逼平衡树(树状数组,线段树)

    [BZOJ3196]二逼平衡树(树状数组,线段树) 题面 BZOJ题面 题解 如果不存在区间修改操作: 搞一个权值线段树 区间第K大--->直接在线段树上二分 某个数第几大--->查询一下 ...

  6. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...

  7. P3157 [CQOI2011]动态逆序对(树状数组套线段树)

    P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...

  8. HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)

    Jam's problem again Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  9. BZOJ 1901 Zju2112 Dynamic Rankings 树状数组套线段树

    题意概述:带修改求区间第k大. 分析: 我们知道不带修改的时候直接上主席树就可以了对吧?两个版本号里面的节点一起走在线段树上二分,复杂度是O((N+M)logN). 然而这里可以修改,主席树显然是凉了 ...

随机推荐

  1. firefox 45 版本

    在做项目的时候,发现45版本的firefox浏览器.声明函数要放在调用者的上方.而firefox的47,48版本则没有这种情况发生.

  2. java里类方法和实例方法

    实例方法相对于静态方法(或者叫类方法)而言没有 static 前缀类般方法被对象拥有(也称之实例方法原因)特点定义时候前面没有 static 前缀本类直接调用时候必须也实例方法内否则调用前必须先实例出 ...

  3. Delphi语言最好的JSON代码库 mORMot学习笔记1(无数评论)

    mORMot没有控件安装,直接添加到lib路径,工程中直接添加syncommons,syndb等到uses里 --------------------------------------------- ...

  4. Linux 内核源码中likely()和unlikely()【转】

    本文转载自:http://blog.csdn.net/tigerjibo/article/details/8279183 ikely()与unlikely()在2.6内核中,随处可见,那为什么要用它们 ...

  5. POJ1077 Eight —— IDA*算法

    主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html 代码一:像BFS那样,把棋盘数组放在结构体中. #include <iostream&g ...

  6. 【摘抄】u3d|unity学习教程与方法

    小编,因为下面这句话,还是决定,只摘链接地址(来自百度经验): http://jingyan.baidu.com/article/19192ad820f17be53e570715.html 经验内容仅 ...

  7. [Selenium] 如何绕过 IE 的安全模式

    自从 IE7 引入 Protected Mode 以来, IE 浏览器的安全性的确得到了一定程度的提高.其原理从本质来讲,在浏览某些需要启用保护模式的页面时,会开启一个新的浏览器会话以完成任务,而此时 ...

  8. Objective-C中的+initialize和+load

    写在前面 近几天花了一些时间了解了一下Objective-C runtime相关的东西,其中涉及到了+load方法,譬如method swizzling通常在category的+load方法中完成.之 ...

  9. ekhtml使用总结

    ekhtml是一个高效SAX方式的HTML解析库. 文件说明 官网下载ekhtml-0.3.2.tar.gz文件解压后,内部包括源码.测试文件.文档.编译脚本等. 如需编译成静态库或动态库后进行集成, ...

  10. 「NOIP2005」「Codevs1106」篝火晚会

    题目描述 Description 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了“小教官”.在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有n个同学,编号从1 ...