J - Super Mario HDU - 4417 线段树 离线处理 区间排序
J - Super Mario HDU - 4417
这个题目我开始直接暴力,然后就超时了,不知道该怎么做,直接看了题解,这个习惯其实不太好。
不过网上的思路真的很厉害,看完之后有点伤心,感觉自己应该可以写的,但是没有写出来。
因为我们要查找一个区间小于等于c的数有多少个,这种区间处理可以用线段树很好的解决,
但是怎么解决呢,我习惯性的直接建树,然后再想怎么做,其实这样不对,
线段树对于我们来说是一个解决问题的工具,不要本末倒置了。
我们想查找一个区间小于等于c的数的个数,用线段树查询很简单,但是怎么建树才可以
让我们每次查询都得到想要的结果呢,这个肯定是不能直接把这个墙的高度直接建树的,应该要先处理一下。
我们可以把查询的高度按升序排序,这样线段树之前更新过的值就不会影响后面的值了。
但是线段树怎么更新呢,这个也可以按升序对墙排个序,这样就解决问题了。
这个思路其实没有特别难想。。。
代码很好敲,但是要注意不要漏掉了,也许都已经更新完了,但是这个答案没有在for循环里面找到。
这个要注意!!!
然后这个题目还可以用主席树写
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <queue>
- #include <vector>
- #include <algorithm>
- #include <iostream>
- #define inf 0x3f3f3f3f
- #define inf64 0x3f3f3f3f3f3f3f3f
- using namespace std;
- typedef long long ll;
- const int maxn = 2e5+;
- ll sum[maxn*], ans[maxn];
- int n, m;
- struct node
- {
- ll num, id;
- }a[maxn];
- struct edge
- {
- ll l, r, h, id;
- edge(ll l=,ll r=,ll h=,ll id=):l(l),r(r),h(h),id(id){}
- }ex[maxn];
- bool cmp(node a,node b)
- {
- return a.num < b.num;
- }
- bool cmp1(edge a,edge b)
- {
- return a.h < b.h;
- }
- void update(int id,int l,int r,int pos)
- {
- if(l==r)
- {
- sum[id] = ;
- return;
- }
- int mid = (l + r) >> ;
- if (pos <= mid) update(id << , l, mid, pos);
- else update(id << | , mid + , r, pos);
- sum[id] = sum[id << ] + sum[id << | ];
- //printf("sum[%d]=%d\n", id, sum[id]);
- }
- ll query(int id,int l,int r,int x,int y)
- {
- if (x <= l && y >= r) return sum[id];
- int mid = (l + r) >> ;
- int ans = ;
- if (x <= mid) ans += query(id << , l, mid, x, y);
- if (y > mid) ans += query(id << | , mid + , r, x, y);
- return ans;
- }
- int main()
- {
- int t;
- scanf("%d", &t);
- for(int cas=;cas<=t;cas++)
- {
- memset(ans, , sizeof(ans));
- memset(sum, , sizeof(sum));
- scanf("%d%d", &n, &m);
- for (int i = ; i <= n; i++) scanf("%lld", &a[i].num), a[i].id = i;
- for (int i = ; i <= m; i++) {
- ll l, r, h;
- scanf("%lld%lld%lld", &l, &r, &h);
- l++, r++;
- ex[i] = edge(l, r, h, i);
- }
- sort(a + , a + + n, cmp);
- sort(ex + , ex + + m, cmp1);
- printf("Case %d:\n", cas);
- int k = ;
- for(int i=;i<=n;i++)
- {
- while(a[i].num>ex[k].h&&k<=m)
- {
- ans[ex[k].id] = query(, , n, ex[k].l, ex[k].r);
- k++;
- }
- update(, , n, a[i].id);
- }
- for (int i = k; i <= m; i++) ans[ex[i].id] = query(, , n, ex[i].l, ex[i].r);//这个注意不要丢掉了!!!
- for (int i = ; i <= m; i++) printf("%lld\n", ans[i]);
- }
- return ;
- }
线段树
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <algorithm>
- #include <queue>
- #include <vector>
- #define inf 0x3f3f3f3f
- #define inf64 0x3f3f3f3f3f3f3f3f
- using namespace std;
- const int maxn = 1e5 + ;
- int n, m, root[maxn], a[maxn], b[maxn], cnt;
- int sum[maxn << ], lc[maxn << ], rc[maxn << ];
- void build(int &rt,int l,int r)
- {
- rt = ++cnt;
- sum[rt] = ;
- if (l == r) return;
- int mid = (l + r) >> ;
- build(lc[rt], l, mid);
- build(rc[rt], mid + , r);
- // printf("rt=%d l=%d r=%d\n",rt,l,r);
- }
- int update(int rt,int l,int r,int pos)
- {
- // printf("ww rt=%d l=%d r=%d pos=%d\n", rt, l, r, pos);
- int id = ++cnt;
- sum[id] = sum[rt] + ;
- // printf("rt=%d sum[%d]=%d\n", rt, id, sum[id]);
- lc[id] = lc[rt], rc[id] = rc[rt];
- if (l == r) return id;
- int mid = (l + r) >> ;
- // printf("mid=%d rt=%d l=%d r=%d pos=%d\n", mid,rt,l,r,pos);
- if (pos <= mid) lc[id] = update(lc[id], l, mid, pos);
- else rc[id] = update(rc[id], mid + , r, pos);
- // printf("rt=%d l=%d r=%d pos=%d\n", rt, l, r, pos);
- return id;
- }
- int query(int l,int r,int u,int v,int h)
- {
- int mid = (l + r) >> ;
- int x = sum[lc[v]] - sum[lc[u]];
- if (l == r) return sum[v] - sum[u];
- int ans = ;
- if (h <= mid) ans = query(l, mid, lc[u], lc[v], h);
- else ans = x + query(mid + , r, rc[u], rc[v], h);
- return ans;
- }
- int main()
- {
- int t;
- scanf("%d", &t);
- for(int cas=;cas<=t;cas++)
- {
- cnt = ;
- scanf("%d%d", &n, &m);
- for (int i = ; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];
- sort(b + , b + + n);
- int len = unique(b + , b + + n) - b - ;
- build(root[], , len);
- // printf("\n\n");
- for (int i = ; i <= n; i++) {
- a[i] = lower_bound(b + , b + + len, a[i]) - b;
- //printf("a[%d]=%d\n", i, a[i]);
- root[i] = update(root[i - ], , len, a[i]);
- // printf("sum[%d]=%d\n", root[i], sum[root[i]]);
- // printf("\n");
- }
- printf("Case %d:\n", cas);
- while(m--)
- {
- int l, r, h;
- scanf("%d%d%d", &l, &r, &h);
- l++, r++;
- h = upper_bound(b + , b + + len, h) - b - ;
- if (h == ) printf("0\n");
- else printf("%d\n", query(, len, root[l - ], root[r], h));
- }
- }
- return ;
- }
主席树
J - Super Mario HDU - 4417 线段树 离线处理 区间排序的更多相关文章
- Super Mario HDU 4417 主席树区间查询
Super Mario HDU 4417 主席树区间查询 题意 给你n个数(编号从0开始),然后查询区间内小于k的数的个数. 解题思路 这个可以使用主席树来处理,因为这个很类似查询区间内的第k小的问题 ...
- E - No Pain No Game 线段树 离线处理 区间排序
E - No Pain No Game HDU - 4630 这个题目很好,以后可以再写写.这个题目就是线段树的离线写法,推荐一个博客:https://blog.csdn.net/u01003321 ...
- Super Mario HDU - 4417 (主席树询问区间比k小的个数)
Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...
- hdu 1166线段树 单点更新 区间求和
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- AC日记——Super Mario hdu 4417
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 3308 线段树单点更新+区间查找最长连续子序列
LCIS Time Limit: 6000/2000 MS (Java/Oth ...
- Super Mario HDU - 4417 (主席树)
Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory ...
- hdu 4288 线段树+离线+离散化
http://acm.hdu.edu.cn/showproblem.php?pid=4288 開始的时候,果断TLE,做的方法是,线段树上只维护%5==3的坐标,比方1 2 3 4 5 6 7 假设 ...
- I Hate It HDU - 1754 线段树 单点修改+区间最值
#include<iostream> #include<cstring> using namespace std; ; int m,n,p; struct node{ int ...
随机推荐
- AJ学IOS 之微博项目实战(3)微博主框架-UIImage防止iOS7之后自动渲染_定义分类
AJ分享,必须精品 一:效果对比 当我们设置tabBarController的tabBarItem.image的时候,默认情况下会出现图片变成蓝色的效果,这是因为ios7之后会对图片自动渲染成蓝色 代 ...
- HashMap之KeySet分析
本篇涵盖 1.HashMap并不是用keySet来存储key的原因及证明 2.keySet方法返回后的remove.add操作原理 一.方法作用 概括一下 1.keySet方法返回map中包含的键的集 ...
- Docker常用命令--ps/attach/run
ps查看container 若查看正在运行的container docker ps 查看所有的container docker ps -a run启动容器 第一次启动container docker ...
- 10.添加script标签,判断onload是否完成
class Tools { static loadScript(url, callback) { let old_script = document.getElementById(url); if ( ...
- React Hooks: useCallback理解
useCallback把匿名回调“存”起来 避免在component render时候声明匿名方法,因为这些匿名方法会被反复重新声明而无法被多次利用,然后容易造成component反复不必要的渲染. ...
- 2020/4/26 大数据的zookeeper分布式安装
大数据的zookeeper分布式安装 **** 前面的文章已经提到Hadoop的伪分布式安装.现在就在原有的基础上安装zookeeper. 首先启动Hadoop平台 [root@master ~]# ...
- JasperReports入门教程(三):Paramters,Fields和Detail基本组件介绍
JasperReports入门教程(三):Paramter,Field和Detail基本组件介绍 前言 前两篇博客带领大家进行了入门,做出了第一个例子.也解决了中文打印的问题.大家跟着例子也做出了de ...
- JS流程图解决方案GoJS
GoJs简介 一个实现交互类图表(比如流程图,树图,关系图,力导图等等)的JS库 GoJS依赖于HTML5,所以请保证您的浏览器版本支持HTML5,当然还要加载这个库. 首先个人建议先下载官方实例的 ...
- Unity Procedural Level Generator 基础总结与功能优化
Procedural Level Generator是在Unity应用商店中发布的一款免费的轻量级关卡生成器: 可以直接搜索关键字在应用商店中查找并下载. 和我之前生成关卡的想法不同,这个插件生成地图 ...
- liunx系统二进制包安装编译mysql数据库
liunx系统二进制包安装编译mysql数据库 # 解压二进制压缩包 [root@localhost ~]# tar xf mysql-5.5.32-linux2.6-x86_64.tar.gz -C ...