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
求l到r中小于k的数字个数。
对于这种l到r的八九不离十是线段树或者主席树,根据题目而定。
这个题目就是利用主席树,由于数据量比较大,所以需要离散化一下。关于离散化和不离散化对于主席树的影响,离散化之后,我们在插入数据的时候,是根据数据在数组中的相对位置,就是lower_bound之后的数。但是不离散化,我们就可以直接按着权值插入数据。权值线段树也是酱紫。我在做主席树或者权值线段树的时候,有时就分不清该是用位置还是权值,就很懵逼。感觉这样判断还是比较正确的,不对的话希望大佬可以指正。
代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#define ll long long
using namespace std;const int maxx=1e5+100;
struct node{int l;int r;int v;
}p[maxx*40];
int a[maxx],b[maxx],root[maxx];
int n,m,num;int build(int l,int r)
{int cur=num++;p[cur].v=0;if(l==r) return cur;int mid=l+r>>1;p[cur].l=build(l,mid);p[cur].r=build(mid+1,r);return cur;
}
int update(int rot,int l,int r,int k)
{int cur=num++;p[cur]=p[rot];p[cur].v++;if(l==r) return cur;int mid=l+r>>1;if(k<=mid) p[cur].l=update(p[rot].l,l,mid,k);else p[cur].r=update(p[rot].r,mid+1,r,k);return cur;
}
int query(int lrot,int rrot,int l,int r,int k)
{if(l==r) return p[rrot].v-p[lrot].v;//到达叶子节点之后,就直接做差就行。int mid=l+r>>1;if(k<=mid) return query(p[lrot].l,p[rrot].l,l,mid,k);else {int ans=p[p[rrot].l].v-p[p[lrot].l].v;ans+=query(p[lrot].r,p[rrot].r,mid+1,r,k);return ans;}
}
int main()
{int t,pos,l,r,k,kk=0;scanf("%d",&t);while(t--){num=1;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];sort(b+1,b+1+n);int len=unique(b+1,b+1+n)-b-1;//离散化root[0]=build(1,len);for(int i=1;i<=n;i++){pos=lower_bound(b+1,b+1+len,a[i])-b;root[i]=update(root[i-1],1,len,pos);}printf("Case %d:\n",++kk);while(m--){scanf("%d%d%d",&l,&r,&k);l++;r++;pos=upper_bound(b+1,b+1+len,k)-b-1;if(pos==0) puts("0");else printf("%d\n",query(root[l-1],root[r],1,len,pos));}}return 0;
}

过来更新一波。这个题也可以不用主席树,也可以用线段树+离线去做。
我们把所有的查询按着k值大小排序,记录之前的位置。也要把原序列按权值大小排序,记录之前的位置。然后遍历去遍历数组。当当前值小于当前的k时,就按着原来的位置插入线段树,否则就直接按着区间找出答案。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;const int maxx=1e5+100;
struct Node{int h,pos;bool operator <(const Node &a)const{return a.h>h;}
}a[maxx];
struct Node1{int l,r,h,id;bool operator <(const Node1 &a)const{return a.h>h;}
}b[maxx];
struct node{int l;int r;int sum;
}p[maxx<<2];
int ans[maxx];
int n,m;inline void pushup(int cur)
{p[cur].sum=p[cur<<1].sum+p[cur<<1|1].sum;
}
inline void build(int l,int r,int cur)
{p[cur].l=l;p[cur].r=r;p[cur].sum=0;if(l==r) return ;int mid=l+r>>1;build(l,mid,cur<<1);build(mid+1,r,cur<<1|1);
}
inline void update(int pos,int v,int cur)
{int L=p[cur].l;int R=p[cur].r;if(L==R){p[cur].sum+=v;return ;}int mid=L+R>>1;if(pos<=mid) update(pos,v,cur<<1);else update(pos,v,cur<<1|1);pushup(cur);
}
inline int query(int l,int r,int cur)
{int L=p[cur].l;int R=p[cur].r;if(l<=L&&R<=r) return p[cur].sum;int mid=L+R>>1;if(r<=mid) return query(l,r,cur<<1);else if(l>mid) return query(l,r,cur<<1|1);else return query(l,mid,cur<<1)+query(mid+1,r,cur<<1|1);
}
int main()
{int t,k=0;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);build(1,n,1);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",&b[i].l,&b[i].r,&b[i].h),b[i].l++,b[i].r++,b[i].id=i;sort(a+1,a+1+n);sort(b+1,b+1+m);for(int i=1,j=1;i<=m;i++){while(a[j].h<=b[i].h&&j<=n) update(a[j++].pos,1,1);ans[b[i].id]=query(b[i].l,b[i].r,1);}printf("Case %d:\n",++k);for(int i=1;i<=m;i++) printf("%d\n",ans[i]);}
}

努力加油a啊,(o)/~

Super Mario HDU - 4417(主席树解决区间数字小于k的个数||线段树+离线)相关推荐

  1. cdoj844-程序设计竞赛 (线段树的区间最大连续和)【线段树】

    http://acm.uestc.edu.cn/#/problem/show/844 程序设计竞赛 Time Limit: 3000/1000MS (Java/Others)     Memory L ...

  2. hdu 3333 Turing Tree 求区间内不同数的和——线段树解法

    http://acm.hdu.edu.cn/showproblem.php?pid=3333 题意:求区间内不同数的和 #include<bits/stdc++.h> using name ...

  3. Zju2112 Dynamic Rankings(树状数组套可持久化权值线段树)

    Zju2112 Dynamic Rankings description solution code description 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须 ...

  4. 【HDU - 4509】湫湫系列故事——减肥记II(合并区间模板 or 离散化标记 or 线段树)

    题干: 虽然制定了减肥食谱,但是湫湫显然克制不住吃货的本能,根本没有按照食谱行动!  于是,结果显而易见-  但是没有什么能难倒高智商美女湫湫的,她决定另寻对策--吃没关系,咱吃进去再运动运动消耗掉不 ...

  5. 【HDU - 4056】Draw a Mess (并查集 or 线段树)

    题干: It's graduated season, every students should leave something on the wall, so....they draw a lot ...

  6. HDU 6681 Rikka with Cake(扫描线、动态开点线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6681 题意 在矩形区域内有k条射线,问这些射线将矩形分成了多少区域 题解 容易发现答案为所有射线交点个数+1. ...

  7. E. Sign on Fence(整体二分 + 线段树维护区间最大连续 1 的个数)

    E. Sign on Fence 给定一个长度为nnn的数组aaa,1≤ai≤1091 \leq a_i \leq 10 ^ 91≤ai​≤109,有mmm次询问,每次给定l,r,kl, r, kl, ...

  8. 区间gcd (带修) 线段树

    题目链接:https://ac.nowcoder.com/acm/contest/1033/B 再次吐槽CH 区间gcd再加区间修改. 一般求gcd的时候辗转相除法. gcd(x,y)=gcd(x,y ...

  9. HDU - 5493 Queue 2015 ACM/ICPC Asia Regional Hefei Online(线段树)

    按身高排序,每个人前面最高的人数有上限,如果超出上限说明impossible, 每次考虑最小的人,把他放在在当前的从左往右第k+1个空位 因为要求字典序最小,所以每次k和(上限-k)取min值. 没有 ...

最新文章

  1. java sessionmanager_java.lang.IllegalStateException:没有SessionManager
  2. 经典基础算法之面试题(系列一)
  3. JDK15新特性密封类可以被继承了!
  4. leetcode292. Nim 游戏
  5. swing中怎么在原来图片的基础上切换第二张图片_摄影比赛原来是这么评出来的!照片点评与修图小赛第10期...
  6. flowable 多人签收_业务流程 BPM、工作流引擎、Flowable、Activiti
  7. PHP下载文件(隐藏真实的下载地址)
  8. Xib实现UICollectionView
  9. Android 编程下的计时器
  10. 阿里巴巴《Java开发手册》官网最全版本及配套 AJCG(Alibaba Java Coding Guidelines)辅助插件下载
  11. 互联网公司招聘--人人网--产品岗-2015年笔试题
  12. linux端口占满,Linux查看端口占用情况,并强制释放占用的端口
  13. Another version of Vue Devtools seems to be installed报错
  14. 知足知不足 有为有不为
  15. matlab中imshow函数输出图像全白全黑问题
  16. 何恺明新作品:VITDet
  17. wish平台入驻需要押金吗?
  18. 1-乙基-3-甲基咪唑四氟硼酸盐/[C2MIm]BF4/cas:143314-16-3/分子量:197.97/离子液体
  19. 关于wangEditor5上传本地图片的详细配置
  20. word文档docx解密助手,word文档docx权限密码如何解开?

热门文章

  1. python输入两个正整数m和n用for循环求其最大公约数_输入两个正整数,m和n,求其最大公约数和最小公倍数。...
  2. php 下拉菜单 搜索,DedeCMS实现百度搜索下拉菜单提示信息功能
  3. linux进程signal,Linux 编程之【进程】signal
  4. oracle .ctl 是什么文件_Oracle误删dual表怎么办?这里教你怎么恢复
  5. php图片抖动,css3,jquery_css3图片抖动,css3,jquery - phpStudy
  6. php断点调试的几种方法
  7. centos 7 升级/安装 git 2.7.3
  8. 算法:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。...
  9. tkinter 类继承的三种方式
  10. Windows遗产之RPC/DCOM:还在用吗,内部又有什么区别?