hdu4302 set或者线段树
题意:
一条蛇生活在一个管子里,然后管子上面的某些位置会一次出现食物,每次蛇都会吃最近的食物,吃完之后就原地不动,等待下一次吃食物,如果有两个食物距离蛇一样远并且都是最近的,那么蛇不会掉头,而是直接按他最后停留的方向走,去吃自己前方的食物,最后给一些命令,问蛇一共走了多少路。
思路:
看完一下就想到了set,结果果断用set过了,后来听说这个题目可以用线段树来做,自己想了下,用线段树也不是很难,结果又写了个线段树,也AC了,set用时359ms,线段树用了515ms,无论是哪个方法,这个题目就是要迅速的找到比当前值大的最小的那个数,和比当前值小的最大的那个数(或者当前值本身),如果是找大于等于的第一个数在set里可以直接 *my_set.lower_bound(now);,如果是小于等于也用同样的方法,只不过是吧所有的数都存成负数就行了,对于线段树也比较好写,每个节点有两个权值,一个是当前区间的最大值,一个是最小值,然后就是简单的更新和查找了,要有一个就是这个题目同一个点可能同时存在多个食物,所以开个数组记录每个节点的食物个数,吃了就--,如果是0就直接删除就行了,具体的看代码。
SET 359ms
#include<stdio.h> #include<set>#define INF 1000000000 using namespace std;set<int>low ,up; int num[110000];int abss(int x) {return x < 0 ? -x : x; }int main () {int t ,n ,m;int a ,b ,cas = 1;scanf("%d" ,&t);while(t--){scanf("%d %d" ,&n ,&m);low.clear() ,up.clear();memset(num ,0 ,sizeof(num));up.insert(INF);low.insert(INF);int now = 0;int sum = 0;int fx = 1;while(m--){scanf("%d" ,&a);if(!a){scanf("%d" ,&b);up.insert(b);low.insert(-b);num[b] ++;}else {a = *up.lower_bound(now);b = *low.lower_bound(-now);if(b != INF) b = -b;if(a == INF && b == INF) continue;if(!abss(a - now)) {if(!--num[a])up.erase(a) ,low.erase(-a);continue;}if(!abss(b - now)){if(!--num[b])up.erase(b) ,low.erase(-b);continue;} if(abss(a - now) < abss(b - now)){sum += abss(a - now);if(now < a) fx = 1;else fx = 2;now = a;if(!--num[a])up.erase(a) ,low.erase(-a);}else if(abss(a - now) > abss(b - now)){sum += abss(b - now);if(now < b) fx = 1;else fx = 2;now = b;if(!--num[b])up.erase(b) ,low.erase(-b);}else {sum += abss(a - now);if(fx == 1 && now < a || fx == 2 && now > a){now = a;if(!--num[a])up.erase(a) ,low.erase(-a);}else {now = b;if(!--num[b])up.erase(b) ,low.erase(-b);}}}}printf("Case %d: %d\n" ,cas ++ ,sum);}return 0; }
字典树 515ms
#include<stdio.h> #include<string.h>#define lson l ,mid ,t << 1 #define rson mid + 1 ,r ,t << 1 | 1 #define INF 100000000 int max[440000] ,min[440000]; int num[110000];int maxx(int x ,int y) {return x > y ? x : y; }int minn(int x ,int y) {return x < y ? x : y; }int abss(int x) {return x < 0 ? -x : x; }void Pushup(int t) {max[t] = maxx(max[t<<1] ,max[t<<1|1]);min[t] = minn(min[t<<1] ,min[t<<1|1]);return ; }void BuidTree(int n) {for(int i = 1 ;i <= n * 4 ;i ++)max[i] = -INF ,min[i] = INF;memset(num ,0 ,sizeof(num));return; }void Update(int l ,int r ,int t ,int a ,int b ,int c) {if(l == r){max[t] = b ,min[t] = c;return ;}int mid = (l + r) >> 1;if(a <= mid) Update(lson ,a ,b ,c);else Update(rson ,a ,b ,c);Pushup(t);return ; }int Query_max(int l ,int r ,int t ,int a ,int b) {if(a <= l && b >= r)return max[t];int mid = (l + r) >> 1;int ans = 0;if(a <= mid) ans = Query_max(lson ,a ,b);if(b > mid) ans = maxx(ans ,Query_max(rson ,a ,b));return ans; }int Query_min(int l ,int r ,int t ,int a ,int b) {if(a <= l && b >= r)return min[t];int mid = (l + r) >> 1;int ans = INF;if(a <= mid) ans = Query_min(lson ,a ,b);if(b > mid) ans = minn(ans ,Query_min(rson ,a ,b)); return ans; }int main () {int t ,m ,n ,i ,a ,b ,sum ,now ,fx ,cas = 1;scanf("%d" ,&t);while(t--){scanf("%d %d" ,&n ,&m);n++ ,now = 1 ,sum = 0 ,fx = 1;BuidTree(n);while(m--){scanf("%d" ,&a);if(!a){scanf("%d" ,&b);num[++b] ++;if(num[b] == 1) Update(1 ,n ,1 ,b ,b ,b);continue;}if(num[now]){sum += 0;if(!--num[now])Update(1 ,n ,1 ,now ,-INF ,INF);continue;}if(now == 1) a = -INF;else a = Query_max(1 ,n ,1 ,1 ,now - 1);if(now == n) b = INF;else b = Query_min(1 ,n ,1 ,now + 1 ,n);if(a == -INF && b == INF) continue;if(abss(a - now) < abss(b - now)){sum += abss(a - now);fx = a < now ? 1 : 2;now = a;if(!--num[now])Update(1 ,n ,1 ,now ,-INF ,INF);}else if(abss(a - now) > abss(b - now)){sum += abss(b - now);fx = b < now ? 1 : 2;now = b;if(!--num[now])Update(1 ,n ,1 ,now ,-INF ,INF);}else {sum += abss(a - now);if(fx == 1 && a < now || fx == 2 && a > now){now = a;if(!--num[now])Update(1 ,n ,1 ,now ,-INF ,INF); }else {now = b;if(!--num[now])Update(1 ,n ,1 ,now ,-INF ,INF);}}}printf("Case %d: %d\n" ,cas ++ ,sum);}return 0;}
hdu4302 set或者线段树相关推荐
- 二逼平衡树——树套树(线段树套Splay平衡树)
题面 Bzoj3196 解析 线段树和Splay两棵树套在一起,常数直逼inf,但最终侥幸过了 思路还是比较简单, 在原数组维护一个下标线段树,再在每一个线段树节点,维护一个对应区间的权值Splay. ...
- 线段树——HDU - 1698
题目含义 就是初始化一堆数为1 可以经过操作把一个区间的数都改变 并求这堆数的总大小 题目分析 有一个 #include<iostream> #include<stdio.h> ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横
不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...
- [bzoj1582][Usaco2009 Hol]Holiday Painting 节日画画_线段树
Holiday Painting 节日画画 bzoj-1582 Usaco-2009 Hol 题目大意:给定两个n*m的01网格图.q次操作,每次将第二个网格图的子矩阵全部变成0或1,问每一次操作后两 ...
- codefores 786B. Legacy(最短路,线段树优化拆点,好题)
题目链接 B. Legacy time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...
- 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树
题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- bzoj1095: [ZJOI2007]Hide 捉迷藏 线段树维护括号序列 点分治 链分治
这题真是十分难写啊 不管是点分治还是括号序列都有一堆细节.. 点分治:时空复杂度$O(n\log^2n)$,常数巨大 主要就是3个堆的初始状态 C堆:每个节点一个,为子树中的点到它父亲的距离的堆. B ...
最新文章
- 魅族适配鸿蒙吗,魅族智能生活发布会新增看点:接入鸿蒙操作系统
- python的concat用法_Pandas串联操作concat()用法介绍
- iphone闪退修复工具_苹果中国回应iPhone致命漏洞:不予置评
- 联海网站开发-操作说明-会员系统及诵读之星
- Python数据分析学习笔记05:用户画像
- DateTimeFormatter,时间格式化与解析日期或时间
- 蔬菜刀行业调研报告 - 市场现状分析与发展前景预测
- 奇异值分解(SVD)详解
- 初始化与赋值哪个效率高?
- 电子书下载:Pro ASP.NET MVC2 Framework 2nd
- bl系列刀片(blade)服务器,HPE Integrity BL870c i6 刀片服务器
- CES 2022|Mobileye推出为自动驾驶汽车打造的全新EyeQ Ultra系统集成芯片
- NASA 用哈勃望远镜定格你的星空
- 英语语态,语态 被动:be的时态变化,一般过去时:一般现在时:一般将来时:主将从现:主祈从现:并列将来:现在完成时:
- 神秘诡异的量子世界是如何毁掉科学家三观的?
- 2018-2019年江苏省高等学校“阿里云大数据技术实战训练营”大学生万人计划学术冬令营开营...
- Android WIFI列表搜索及无线热点的开启和关闭
- modbus寄存器、功能码、报文结构解析
- Acro Design Pro vue - table 行点击高亮显示
- [转]加盐hash保存密码的正确方式
热门文章
- Spring《二》 Bean的生命周期
- 两阶段提交协议的异常处理
- Automation Test in Maya Plugin Development
- windows下python安装Numpy和Scipy模块
- C# 海康DVR客户端开发系列(2)—— 封装API
- 冬天了,麦克风/话筒 有杂音 的原因!
- sqlserver 查找数据混排
- mysql -h139.129.205.80 -p test_db_dzpk db.dump
- day19_MD5加密_Apache DBUtils_监听器 知识回顾
- iOS 集成银联支付swift