题意:

      一条蛇生活在一个管子里,然后管子上面的某些位置会一次出现食物,每次蛇都会吃最近的食物,吃完之后就原地不动,等待下一次吃食物,如果有两个食物距离蛇一样远并且都是最近的,那么蛇不会掉头,而是直接按他最后停留的方向走,去吃自己前方的食物,最后给一些命令,问蛇一共走了多少路。

思路:

      看完一下就想到了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或者线段树的更多相关文章

  1. HDU4302 线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4302 , 可以用线段树,也可以STL中的map,multiset,优先队列中的任何一个解决(可我只会线 ...

  2. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  3. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  4. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  5. codevs 1080 线段树点修改

    先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...

  6. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  7. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  8. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...

  9. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

随机推荐

  1. 操作系统---在内核中重新加载GDT和堆栈

    摘要 用BIOS方式启动计算机后,BIOS先读取引导扇区,引导扇区再从外部存储设备中读取加载器,加载器读取内核.进入内核后,把加载器中建立的GDT复制到内核中. 这篇文章的最大价值也许在末尾,对C语言 ...

  2. 漏洞复现-CVE-2016-4437-Shiro反序列化

        0x00 实验环境 攻击机:Win 10 靶机也可作为攻击机:Ubuntu18 (docker搭建的vulhub靶场)(兼顾反弹shell的攻击机) 0x01 影响版本 Shiro <= ...

  3. 漏洞复现-Bash之一键破壳

        注:使用docker搭建测试环境 (1)访问搭建的环境网址:http://192.168.11.101:8081/ (2)使用burp拦截数据包,并修改User-Agent的内容: (3)使用 ...

  4. LNMP配置——Nginx配置 —— 用户认证

    一.配置 再来创建一个新的虚拟主机 #cd /usr/local/nginx/conf/vhost #vi test.com.conf 写入: server { listen 80; server_n ...

  5. MyBatis(八):MyBatis插件机制详解

    MyBatis插件插件机制简介 ​ MyBatis插件其实就是为使用者提供的自行拓展拦截器,主要是为了可以更好的满足业务需要. ​ 在MyBatis中提供了四大核心组件对数据库进行处理,分别是Exec ...

  6. P3388 【模板】割点(割顶) 题解 (Tarjan)

    题目链接 P3388 [模板]割点(割顶) 解题思路 最近学的东西太杂了,多写点博客免得自己糊里糊涂的过去了. 这个题求割点,感觉这篇文章写得挺好. 割点是啥?如果去掉这个点之后连通图变成多个不连通图 ...

  7. VSCode 微信小程序扩展开发

    写在前面 为什么要开发这个扩展呢,是因为微信开发者工具自身不支持页面引入组件的跳转,人工根据引入组件路径查看对应代码的方式,效率偏低.就形如这样的json文件,引入了多个组件,比如要查看 " ...

  8. Nodejs学习笔记(5) 文件上传系统实例

    目录 2018.8.4更新:  MySQL可以存放几乎任何类型的数据(图片.文档.压缩包等),但这不是最好的解决方案,正常情况下都是在数据库中存放文件路径,图片.音乐.视频.压缩包.文档等文件存放在硬 ...

  9. python 序列与字典

    序列概念: 序列的成员有序排列,可以通过下标访问到一个或几个元素,就类似与c语言的数组. 序列的通用的操作: 1:索引 11 = [1,2,3,4] 11[0] = 1 2:切片 11[1,2,3,4 ...

  10. 对象存储服务-Minio

    Mino 目录 Mino 对象存储服务 Minio 参考 Minio 架构 为什么要用 Minio 存储机制 纠删码 MinIO概念 部署 单机部署: Docker 部署Minio 分布式Minio ...