题意:输入一个t,表示有t组测试数据;

接下来一行,输入两个数,k,m,其中k表示这个辆车最多可以坐这么多人,m表示有m次询问能否上车;

每一次询问,输入两个数a,b,表示该乘客能否在a站台上车,b站台下车,乘车区间为(a,b--),先后次序;

即我每次询问,你就判断在a站台处将会有多少人还在车上,小于k则表示能够上车,更新数据,反之不能上车;

解题思路:这道题很明显就是线段树的区间更新,即判断线段的重叠次数。

按照刘汝佳书上写的代码WA了,不知道为什么。。。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;const int maxn = 1e6+5;
int add[maxn<<2],Max[maxn<<2],l,r,_max;
int ans[maxn];void maintain(int o,int L,int R)
{int lc = o*2,rc = o*2+1;Max[o] = 0;if(R > L){Max[o] = max(Max[lc],Max[rc]);}Max[o] += add[o];
}void update(int o,int L,int R,int v)
{int lc = o*2, rc = o*2+1;if(l <= L && R <= r){add[o] += v;}else{int M = (L + R) >> 1;if(M >= l) update(lc,L,M,v);if(r > M) update(rc,M+1,R,v);}maintain(o,L,R);
}void query(int o,int L,int R,int addv)
{int lc = o*2, rc = o*2+1;if(l <= L && R <= r){_max = max(_max,Max[o] + addv);}else{int M = (L + R) >> 1;if(l <= M) query(lc,L,M,addv+add[lc]);if(r > M) query(rc,M+1,R,addv+add[rc]);}
}int main()
{int t,cas = 1,len;scanf("%d",&t);while(t--){memset(add,0,sizeof(add));memset(Max,0,sizeof(Max));len = 0;int k,q;scanf("%d%d",&k,&q);for(int i = 1; i <= q; i++){scanf("%d%d",&l,&r);r--;_max = 0;query(1,1,1000000,0);if(_max < k){update(1,1,1000000,1);ans[len++] = i;}}printf("Case %d:\n",cas++);for(int i = 0; i < len; i++)printf("%d ",ans[i]);printf("\n\n");}return 0;
}

看了别人的代码,采用了一种lazy思想,也就是用一层更新一层,如果我在某一层能够找到符合要求的区间,那么就不更新它的子节点了,等到我需要它的子节点时,再把子节点更新了。。。总之是这样的一种思想,结合代码多思考下。。。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1000005;
int ans[N];
struct node
{int l,r,v,lazy;
}node[N<<2];    //  线段树的空间大概是数组空间的4倍;
void build(int l,int r,int numb)    //  线段树的建立;
{node[numb].l=l;node[numb].r=r;node[numb].v=0;node[numb].lazy=0;              //  用了lazy思想,提高了效率;if(l==r) return;int mid=(l+r)>>1;build(l,mid,numb<<1);build(mid+1,r,numb<<1|1);
}
void PushUp(int numb)               //  往上往父节点方向更新数据;但是这里不是左右儿子的和,而是最大值,因为是站台人数;
{node[numb].v=max(node[numb<<1].v,node[numb<<1|1].v);
}
void PushDown(int numb)             //  向下往左右儿子方向更新数据;
{node[numb<<1].lazy+=node[numb].lazy;node[numb<<1|1].lazy+=node[numb].lazy;node[numb<<1].v+=node[numb].lazy;node[numb<<1|1].v+=node[numb].lazy;node[numb].lazy=0;              //  更新完了要清零;
}
void Insert(int l,int r,int numb)   //  插入更新数据;
{if(node[numb].l>=l&&node[numb].r<=r)    //  如果区间完全重合,则不需要再往下更新了,先保存起来,可以节约很多的时间(lazy思想){node[numb].v+=1;node[numb].lazy+=1;return;}if(node[numb].lazy) PushDown(numb);     //  因为没有找到完全重合的区间,所以要先更新下一层区间;int mid=(node[numb].r+node[numb].l)>>1;if(l>mid) Insert(l,r,numb<<1|1);else if(r<=mid) Insert(l,r,numb<<1);else{Insert(l,mid,numb<<1);Insert(mid+1,r,numb<<1|1);}PushUp(numb);       //  最后还得往上返回,更新父节点区间;
}
int query(int l,int r,int numb)     //  查询区间l到r;
{if(node[numb].l>=l&&node[numb].r<=r){return node[numb].v;}if(node[numb].lazy) PushDown(numb);     //  道理同48行;int mid=(node[numb].r+node[numb].l)>>1;if(l>mid) return query(l,r,numb<<1|1);else if(r<=mid) return query(l,r,numb<<1);else{return max(query(l,mid,numb<<1),query(mid+1,r,numb<<1|1));  //  道理同28行;}
}
int main()
{int t,Case=1,len=0,k,m,a,b;scanf("%d",&t);while(t--){len=0;memset(ans,0,sizeof(ans));scanf("%d%d",&k,&m);build(1,1000000,1);for(int i=0;i<m;i++){scanf("%d%d",&a,&b);b--;                    //  这里有一个问题,就是乘客从a上车,b下车,所以乘客在车上的区间为(a,b--);if(query(a,b,1)<k){     //  表示可以上车;ans[len++]=i+1;Insert(a,b,1);}}printf("Case %d:\n",Case++);for(int i=0; i<len; i++)    printf("%d ",ans[i]);printf("\n\n");}return 0;
}

hdu 3577(线段树区间更新)相关推荐

  1. POJ 2777 ZOJ 1610 HDU 1698 --线段树--区间更新

    直接将这3题 放一起了  今天在做线段树的东西 这3个都是区间更新的 查询方式互相不同 反正都可以放到一起吧 直接先上链接了 touch me touch me touch me 关于涉及到区间的修改 ...

  2. hdu 1698(线段树区间更新)

    解题思路:线段树区间更新水题. #include<iostream> #include<cstdio> #include<cstring> using namesp ...

  3. hdu 3954(线段树区间更新)

    转载标记处:http://www.cnblogs.com/wang-jue/articles/2920341.html 思路:这道题所得到的经验与每个英雄的等级有关,一般的可能就用线段树一直更新到每一 ...

  4. hdu 5124(线段树区间更新+lazy思想)

    http://acm.hdu.edu.cn/showproblem.php?pid=5124 题意:区间覆盖次数问题. 解题思路:线段树水之. #include<iostream> #in ...

  5. hdu 5692 Snacks(dfs序+线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5692 解题思路:这道题是树节点的点权更新,而且涉及到子树,常用的思路是利用dfs序,用线段树来对区间进 ...

  6. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  7. Just a Hook(线段树区间更新)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 In the game of DotA, Pudge's meat hook is actual ...

  8. ZOJ 1610 Count the Colors (线段树区间更新)

    题目链接 题意 : 一根木棍,长8000,然后分别在不同的区间涂上不同的颜色,问你最后能够看到多少颜色,然后每个颜色有多少段,颜色大小从头到尾输出. 思路 :线段树区间更新一下,然后标记一下,最后从头 ...

  9. hihoCoder 1080 : 更为复杂的买卖房屋姿势 线段树区间更新

    #1080 : 更为复杂的买卖房屋姿势 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho都是游戏迷,"模拟都市"是他们非常喜欢的一个游戏 ...

  10. CodeForces - 272C Dima and Staircase (线段树区间更新)

    题意: 见以下样例,给出 5 个区间,每个区间的高度已知.一共 4 次操作.每次操作都是从最左边开始向下垒一个宽为 w 高为h 的木块,过程见下图. 问每次垒木块的高度是多少? Input 5 1 2 ...

最新文章

  1. 【杠精】切屏屏蔽和复制,怎么办--有方法解除移动切屏和复制网大限制
  2. C#方法参数传递-同时使用ref和out关键字
  3. webDriver测试百度登录java版
  4. 新年新气象,2008年是我创业关键的一年!
  5. java 如何使用dylib,如何在应用程序中使用dylib文件?
  6. 富文本编辑器中空格转化为a_熙态农业:富硒鸡蛋有什么营养价值?
  7. oracle传输表空间功能测试(含详细过程)
  8. 【切图】门户网首页模板一 (类似CSDN)
  9. 【Python】【Flask】前端调用后端方法返回页面
  10. oracle11g的adg需要付费嘛,Oracle11g ADG 搭建
  11. nfs 端口_Linux挂载NFS,偶发执行df命令卡顿
  12. (转)BlackRock:全球最大资管公司如何一步步倒戈人工智能?
  13. C语言图书借阅管理系统
  14. 显示更清晰,书写更专业:汉王手写电纸本N10发布
  15. SRE 到底是干什么的??
  16. 国产手机品牌线下渠道将崩溃,难怪618纷纷割肉抛售努力逃生
  17. mysql服务starting_MySQl服务无法启动(Starting MySQL.The server quit withou)
  18. 切西瓜法实现微信抢红包功能
  19. 31 家企业入选阿里云首期云原生加速器,共建云原生行业新生态
  20. HTML+CSS+JS 科学计算器apk+源码

热门文章

  1. 直播预告丨6 大趋势,5 种核心能力,证券业数字新基建趋势全面解读
  2. Maven学习总结(十)——使用Maven编译项目gbk的不可映射问题
  3. 虚拟机中RedHat Linux系统安装
  4. 全文检索引擎Solr系列——Solr核心概念、配置文件
  5. 使一个div垂直+水平居中的几种方法
  6. MVC源码学习之AuthorizeAttribute
  7. 转:openTSDB 2.0 安装
  8. 7月13日微软MVP社区夏日巡讲北京站活动现场图集
  9. butter fly graph
  10. 永远不要让女生帮你寄领带