一開始实在是不知道怎么做,后来经过指导,猛然发现,仅仅须要记录某个区间内是否有值就可以。

flag[i]:代表i区间内,共同拥有的蛋糕数量。

放置蛋糕的时候非常好操作,单点更新。

ip:老鼠当前的位置

寻找吃哪一个蛋糕的时候:

1,要寻找0-ip这个区间内,位置最大的一个蛋糕的位置,记为ll。

2,要寻找ip-n这个区间内,位置最小的一个蛋糕的位置,记为rr。

找到ll,rr之后,就能够依据ll,rr跟ip的关系来确定该吃ll还是rr了。

怎样寻找ll呢?

假设在某个区间的右半边区间找到了一个数,那么,这个区间的左半边区间肯定就不用寻找了。

假设这个区间的大小为1,那么这个区间内须要的数就肯定是这个数了。

假设某个区间的flag为0,那么这个区间肯定不存在蛋糕。

假设某个区间不包括0-ip,那么这个区间也肯定找不到ll。

于是,我们写出了寻找ll的函数:

int query(int ll,int rr,int l,int r,int rt)
{
if(rr<l||ll>r)return -INF;
if(flag[rt]==0)return -INF;
if(l==r)
{
if(flag[rt])return l;
else return -INF;
}
int ans=-INF;
ans=query(ll,rr,rson);
if(ans==-INF)ans=query(ll,rr,lson);
return ans;
}

寻找rr的原理与寻找ll的原理同样。

整体代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<stack>
using namespace std;
#define INF 99999999
#define lmin 0
#define rmax n
#define lson l,(l+r)/2,rt<<1
#define rson (l+r)/2+1,r,rt<<1|1
#define root lmin,rmax,1
#define maxn 110000
int flag[maxn*4];
void push_up(int rt)
{
flag[rt]=flag[rt<<1]+flag[rt<<1|1];
}
void push_down(int rt)
{ }
void creat(int l,int r,int rt)
{
flag[rt]=0;
if(l!=r)
{
creat(lson);
creat(rson);
}
}
void update(int st,int x,int l,int r,int rt)
{
if(r<st||l>st)return;
if(l==r&&l==st)
{
flag[rt]+=x;
return;
}
update(st,x,lson);
update(st,x,rson);
push_up(rt);
}
int query(int ll,int rr,int l,int r,int rt)
{
if(rr<l||ll>r)return -INF;
if(flag[rt]==0)return -INF;
if(l==r)
{
if(flag[rt])return l;
else return -INF;
}
int ans=-INF;
ans=query(ll,rr,rson);
if(ans==-INF)ans=query(ll,rr,lson);
return ans;
}
int query1(int ll,int rr,int l,int r,int rt)
{
// cout<<ll<<" "<<rr<<" "<<l<<" "<<r<<" "<<flag[rt]<<endl;
if(rr<l||ll>r)return INF;
if(flag[rt]==0)return INF;
if(l==r)
{
if(flag[rt])return l;
else return INF;
}
int ans=INF;
ans=query1(ll,rr,lson);
if(ans==INF)ans=query1(ll,rr,rson);
return ans;
}
int main()
{
int cas,T;
int n,m;
int l,r,mid;
int k,a,b,c;
int m1,m2;
scanf("%d",&T);
cas=0;
while(T--)
{
cas++;
int sum=0;
scanf("%d%d",&n,&m);
creat(root);
int ip=0;
int f=0;
while(m--)
{
scanf("%d",&k);
if(k==1)
{
int l=query(0,ip,root);
int r=query1(ip,n,root);
// cout<<l<<" "<<r<<endl;
if(l>=0||r<=n)
{
int ll=ip-l;
int rr=r-ip;
if(ll==rr&&f==1)mid=l;
else if(ll==rr&&f==0)mid=r;
else if(ll<rr)
{
mid=l;
f=1;
}
else if(ll>rr)
{
mid=r;
f=0;
}
int cha=mid-ip;
if(cha<0)cha=-cha;
sum+=cha;
ip=mid;
update(mid,-1,root);
}
}
else
{
scanf("%d",&a);
update(a,1,root);
}
}
printf("Case %d: %d\n",cas,sum);
}
return 0;
}

hdu-4302-Holedox Eating-线段树-单点更新,有策略的单点查询的更多相关文章

  1. HDU 4302 Holedox Eating (线段树模拟)

    题意:一个老鼠在一条长度为L的直线上跑,吃蛋糕,老鼠只能沿直线移动.开始时没有蛋糕,老鼠的初始位置是0. 有两个操作,0 x 代表在位置x添加一个蛋糕: 1 代表老鼠想吃蛋糕.老鼠每次都会选择离自己最 ...

  2. hdu 4302 Holedox Eating(优先队列/线段树)

    题意:一只蚂蚁位与原点,在x轴正半轴上会不时地出现一些蛋糕,蚂蚁每次想吃蛋糕时选取最近的去吃,如果前后距离相同,则吃眼前的那一块(即方向为蚂蚁的正前),求最后蚂蚁行进距离. 思路:优先队列q存储蚂蚁前 ...

  3. HDU 3577 Fast Arrangement (线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577 题意不好理解,给你数字k表示这里车最多同时坐k个人,然后有q个询问,每个询问是每个人的上车和下车 ...

  4. ZOJ 5638——Prime Query——————【线段树区间更新,区间查询,单点更新】

    Prime Query Time Limit: 1 Second      Memory Limit: 196608 KB You are given a simple task. Given a s ...

  5. HDU 4902 Nice boat --线段树(区间更新)

    题意:给一个数字序列,第一类操作是将[l,r]内的数全赋为x ,第二类操作是将[l,r]中大于x的数赋为该数与x的gcd,若干操作后输出整个序列. 解法: 本题线段树要维护的最重要的东西就是一个区间内 ...

  6. hdu 1698+poj 3468 (线段树 区间更新)

    http://acm.hdu.edu.cn/showproblem.php?pid=1698 这个题意翻译起来有点猥琐啊,还是和谐一点吧 和涂颜色差不多,区间初始都为1,然后操作都是将x到y改为z,注 ...

  7. HDU 4302 Holedox Eating (STL + 模拟)

    Holedox Eating Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. hdu 4302 Holedox Eating

    http://acm.hdu.edu.cn/showproblem.php?pid=4302 #include <cstdio> #include <cstring> #inc ...

  9. HDU 4302 Holedox Eating(multiset)

    http://acm.hdu.edu.cn/showproblem.php?pid=4302 题意: 在一条直线上,会有多条命令,如果是0,那么就会在x位置处出现一个蛋糕,如果是1,某人就会找到最近的 ...

  10. hdu 3397 Sequence operation 线段树 区间更新 区间合并

    题意: 5种操作,所有数字都为0或1 0 a b:将[a,b]置0 1 a b:将[a,b]置1 2 a b:[a,b]中的0和1互换 3 a b:查询[a,b]中的1的数量 4 a b:查询[a,b ...

随机推荐

  1. 简识UML语言(转)

    在学习过程中用到了一些框图,用于绘画框图的语言数不胜数,本篇将就学习中用的一款绘画框图的语言做个简单的介绍. 直奔主题,采用一种可视化的面向对象的建模语言---UML,UML使用一些标准的圆形元素直观 ...

  2. 最佳实践:Windows Azure 网站 (WAWS)

     编辑人员注释:本文章由 Windows Azure 网站团队的项目经理Sunitha Muthukrishna 撰写. Windows Azure 网站 (WAWS) 允许您在 Windows ...

  3. POCO C++ lib开发环境构建

    Welcome Thank you for downloading the POCO C++ Libraries and welcome to the growing community of POC ...

  4. iOS开展-CocoaPods安装和使用教程

    原文链接: iOS开展-CocoaPods安装和使用教程 修正已经增加了自己的理解. CocoaPods安装和使用教程 Code4App 原创文章.转载请注明出处:http://code4app.co ...

  5. WLAN和WIFI的区别

    在刚刚为大家介绍的wifi上网是什么意思?文章中为大家介绍了什么wifi无线上网,但大家可能会有这样的疑问,听说最多的应该是WLAN无线上网,很多笔记本电脑使用的都是WLAN无线上网,那么wlan和w ...

  6. System.Web.HttpContext.Current.Session为NULL值的问题?

    自定义 HTTP 处理程序,从IHttpHandler继承,在写System.Web.HttpContext.Current.Session["Value"]的时 候,没有问题,但 ...

  7. plsql developer连接64位Oracle11g的解决方法

    1)安装Oracle 11g 64位 2)安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0)下载地址:http://www.oracle.co ...

  8. 快速构建ASP.NET MVC Admin主页

    前言 后台开发人员一般不喜欢调样式,搞半天样式出不来,还要考虑各种浏览器兼容,费心费力不讨好,还好互联网时代有大量的资源共享,避免我们从零开始,现在就来看怎么快速构建一个ASP.NET MVC后台管理 ...

  9. struct 如何存储指针类型的值

    通过 __unsafe_unretained标示符标示指针类型的值,否则xcode会报以下错误(前提,你使用的是ARC模式): ARC forbids Objective-C objects in s ...

  10. 使用Groovy进行依赖注入

    为什么选择Groovy? 传统的依赖注入是XML,对我而言,可读性太差,太不美观,强烈地想换一个方式进行依赖注入,Groovy作为XML的替代方案,在Spring4之后被引入,是基于JVM的一门方言, ...