博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu-4302-Holedox Eating-线段树-单点更新,有策略的单点查询
阅读量:4637 次
发布时间:2019-06-09

本文共 2500 字,大约阅读时间需要 8 分钟。

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

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
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
#include
#include
#include
#include
#include
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 110000int 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)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
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<
<<" "<
<<" "<
<<" "<
<<" "<
<
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<
<<" "<
<
=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=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;}

转载于:https://www.cnblogs.com/mengfanrong/p/3867793.html

你可能感兴趣的文章
ASP.NET MVC Identity 兩個多個連接字符串問題解決一例
查看>>
过滤器与拦截器区别
查看>>
USACO 1.5.4 Checker Challenge
查看>>
第二阶段站立会议7
查看>>
[18]Debian Linux Install GNU GCC Compiler and Development Environment
查看>>
JAVA多线程
查看>>
ACE(Adaptive Communication Environment)介绍
查看>>
delphi 更改DBGrid 颜色技巧
查看>>
python编码问题
查看>>
POJ 2031 Building a Space Station
查看>>
面向对象1
查看>>
编程开发之--java多线程学习总结(5)
查看>>
register_globals(全局变量注册开关)
查看>>
as3调用外部swf里的类的方法
查看>>
如何让 zend studio 10 识别 Phalcon语法并且进行语法提示
查看>>
任意阶幻方(魔方矩阵)C语言实现
查看>>
视频教程--ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库
查看>>
第五次作业
查看>>
织梦教程
查看>>
杭电多校 Harvest of Apples 莫队
查看>>