Super Mario

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

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
 
Source
 
 
 
题意就是求区间小于等于H的数的个数。
 
这道题写的时间有点长,错在这几个地方:
(1)因为数是从0开始的,所以查询的时候,区间l[i]和r[i]应该+1,查询的时候就l[i]-1,r[i],或者区间l[i]和r[i]不变化,查询的时候,就l[i],r[i]+1。
(2)因为查询的是小于等于H的数,所以H也应该离散化,找对应的数,而不是直接查询,这里错了好久才发现。
(3)数组开小了,杭电这道题数组开小了报的是WA,把maxn=1e5+10改成2e5+10就过了。
 
还有一点,其实是自己脑子不好特意测了一下。
因为数据已经离散化处理过了,所以查询的时候不会有重复的数,所以查询的时候,lower_bound()和upper_bound()都可以。
 
//int cnt=lower_bound(b+1,b+1+d,h[i])-b;
int cnt=upper_bound(b+,b++d,h[i])-b-;

以上两种都是对的。

代码:

 //无修改区间-可持久化线段树(权值线段树+可持久化)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii; const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int inf=0x3f3f3f3f;
const int maxn=2e5+;
const int maxm=+;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson l,m
#define rson m+1,r int a[maxn],b[maxn],sum[maxn<<],ls[maxn<<],rs[maxn<<];//sum线段树里保存的值,L左儿子,R右儿子
int n,m,sz=; void build(int &rt,int l,int r)//建棵空树
{
rt=++sz;sum[rt]=;//动态开点,初始值为0,空树
if(l==r){
return ;
} int m=(l+r)>>;
build(ls[rt],lson);
build(rs[rt],rson);
} void update(int pre,int &rt,int l,int r,int p,int c)
{
rt=++sz;sum[rt]=sum[pre]+c;//插入序列,首先继承以前的线段树 然后直接单点+1就可以
ls[rt]=ls[pre];rs[rt]=rs[pre];
if(l==r){
return ;
} int m=(l+r)>>;
if(p<=m) update(ls[pre],ls[rt],lson,p,c);//因为右边不需要更新,所以覆盖掉左边
else update(rs[pre],rs[rt],rson,p,c);
//sum[rt]=sum[ls[rt]]+sum[rs[rt]];
} int query(int pre,int rt,int L,int R,int l,int r)//查询l到r区间就是第r次插入减去第l-1次插入后的线段树的样子
{
if(L>R) return ;
if(L<=l&&r<=R){
return sum[rt]-sum[pre];
} int ret=;
int m=(l+r)>>;
if(L<=m) ret+=query(ls[pre],ls[rt],L,R,lson);
if(R> m) ret+=query(rs[pre],rs[rt],L,R,rson);
return ret;
} int rt[maxn],l[maxn],r[maxn],h[maxn]; int main()
{
int t;
scanf("%d",&t);
for(int cas=;cas<=t;cas++){
scanf("%d%d",&n,&m);
sz=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
}
for(int i=;i<=m;i++){
scanf("%d%d%d",&l[i],&r[i],&h[i]);
b[i+n]=h[i];
l[i]++,r[i]++;
}
sort(b+,b++n+m);//首先把值全部排序去重,用于建权值线段树,权值线段树保存的内容是值的数量。
int d=unique(b+,b++n+m)-(b+);
build(rt[],,d);
for(int i=;i<=n;i++) //按照序列顺序插入值
{
int p=lower_bound(b+,b++d,a[i])-b;
update(rt[i-],rt[i],,d,p,);
}
printf("Case %d:\n",cas);
for(int i=;i<=m;i++)
{
//int L=1,R=upper_bound(b+1,b+1+d,h)-b-1;
//int cnt=lower_bound(b+1,b+1+d,h[i])-b;
int cnt=upper_bound(b+,b++d,h[i])-b-;
//printf("%d\n",query(rt[l[i]],rt[r[i]+1],1,cnt,1,d));
//printf("%d\n",query(rt[l],rt[r+1],1,cnt,1,d));
printf("%d\n",query(rt[l[i]-],rt[r[i]],,cnt,,d));
}
}
return ;
}

菜的难受。。。

HDU 4417.Super Mario-可持久化线段树(无修改区间小于等于H的数的个数)的更多相关文章

  1. HDU 2665.Kth number-可持久化线段树(无修改区间第K小)模板 (POJ 2104.K-th Number 、洛谷 P3834 【模板】可持久化线段树 1(主席树)只是输入格式不一样,其他几乎都一样的)

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. HDU 4348.To the moon SPOJ - TTM To the moon -可持久化线段树(带修改在线区间更新(增减)、区间求和、查询历史版本、回退到历史版本、延时标记不下放(空间优化))

    To the moon Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  3. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  4. HDU 4417 Super Mario(线段树)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  5. HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. hdu 4417 Super Mario/树套树

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意很简单,给定一个序列求一个区间 [L, R,]中小于等于H的元素的个数. 好像函数式线段树可 ...

  7. HDU 4417 Super Mario (划分树)(二分)

    Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. HDU 4417 Super Mario

    题解:函数式线段树求区间小于等于k的数有几个,离线做法,首先将所有询问和序列一起离散,然后用函数式线段树处理. #include <map> #include <cstdio> ...

  9. HDU - 1754 I Hate It (线段树点修改求最大值)

    题意:有N个学生M条操作,0<N<=200000,0<M<5000,要么查询某区间内学生的最高分,要么更改某学生的成绩. 分析:原理和线段树点修改求和类似. #include& ...

随机推荐

  1. git代码冲突

    如果系统中有一些配置文件在服务器上做了配置修改,然后后续开发又新添加一些配置项的时候, 在发布这个配置文件的时候,会发生代码冲突: error: Your local changes to the f ...

  2. Epoll模型讲解

    1.流模型 首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象. 不管是文件,还是套接字,还是管道,我们都可以把他们看作流. 之后我们来讨论I/O的操作, ...

  3. Maven -- 将引用的本地jar文件打进war包里

    我们在做maven项目开发中有时候引用了本地第三方包,例如: <dependency> <groupId>org.artofsolving.jodconverter</g ...

  4. HDU 1070 Milk (模拟)

    题目链接 Problem Description Ignatius drinks milk everyday, now he is in the supermarket and he wants to ...

  5. NodeJS中Buffer模块详解

    一,开篇分析 所谓缓冲区Buffer,就是 "临时存贮区" 的意思,是暂时存放输入输出数据的一段内存. JS语言自身只有字符串数据类型,没有二进制数据类型,因此NodeJS提供了一 ...

  6. hdu 1599 find the mincost route (最小环与floyd算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1599 find the mincost route Time Limit: 1000/2000 MS ...

  7. 设计模式之Prototype

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 为什么要用Prototype ...

  8. oracle中有关表的操作

    在Oracle中查看所有的表: select * from tab/dba_tables/dba_objects/cat; 看用户建立的表 : select table_name from user_ ...

  9. ms17-010 攻击win7漏洞复现

    只是为了好玩重新写一篇.利用还是很简单的. 将下载下来的rb放置在:/usr/share/metasploit-framework/modules/exploits/windows/smb/ 目录下 ...

  10. Caffe学习笔记2

    Caffe学习笔记2-用一个预训练模型提取特征 本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 欢迎关注我的博客:http://blog.csdn.net/hi ...