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. Activity-ListView

    在手机中经常有列表方式.如果Activity中只有唯一一个List(这也是通常的情况),可以继承ListActivity来实现.我们用两个例子来学习List. List例子一:利用Android自带的 ...

  2. [Android篇]Android Studio + Genymotion 一夜无眠 ,超级详细版本[请使用新版2.0]

    环境说明:这里很重要,因为我在windows10中吃过很多的亏 操作系统: windows 7 64位系统 JDK 64位 : jdk1.7.0_75 注意我这里吃过亏!都用64位的! Android ...

  3. js for等循环 跳出多层循环

    js for 循环 跳出多层循环 ,,,,,,,]; // 8个数 ,,,,,,,]; //8个数 testFor(); console.log(') function testFor() { ;k& ...

  4. sublime 常用插件 感觉比较全了 够用了

    插件介绍 Package Control 功能:安装包管理 简介:sublime插件控制台,提供添加.删除.禁用.查找插件等功能 使用:https://sublime.wbond.net/instal ...

  5. 20、redis和memcached比较?

    1.Redis和Memcache都是将数据存放在内存中,都是内存数据库.不过memcache还可用于缓存其他东西,例如图片.视频等等: 2.Redis不仅仅支持简单的k/v类型的数据,同时还提供lis ...

  6. 双关键字LIS

    首先对于双关键字的LIS有一个比较暴力的方法,就是线段树套平衡树,我们把双关键字的LIS抽象成二维坐标系中的点,这样我们对于当前转移的点i(x,y),需要找的就是在(xx,yy)xx<x,yy& ...

  7. HTML JS文字闪烁实现(项目top.htm分析)

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-- saved from ur ...

  8. 5.0docer 网络链接

    docker0 :linux的虚拟网桥 虚拟网桥特点: 1.可以设置ip地址 2.相当于拥一个隐藏的虚拟网卡     安装网桥工具 apt-get install bridge-utils brctl ...

  9. ie8下input文字偏上select文字偏下

    1.ie8下input文字偏上 正常情况下input的显示情况如下 当设置input的高度时,就会出现文字不垂直居中偏上的情况,如图 解决方案 强input的行高line-height与其高度设置一致 ...

  10. java封装示例代码

    package com.imooc; public class Telphone { private float screen; private float cpu; private float me ...