题目链接:点击查看

题目大意:给定n个村庄,初始化全部连接为一条直线,需要依次执行m个操作,D表示摧毁第i个村庄的连接,R表示恢复最后一

个被摧毁的村庄的连接,Q表示询问包括本身在内,与第i个村庄相连接的有多少个村庄(间接连接也算)

题目分析:这个题需要用到区间合并的思想,并且用线段树来实现,应该算是个裸题了,把pushup的板子套进线段树里就OK,

不过这个题的query函数比较难写,我会在代码中写上相应注释来帮助理解,其余的函数就都是线段树的基础了

上代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<sstream>
#include<cmath>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=5e4+100;struct Node
{int l,r;int ll,rr,all;
}tree[N<<2];void build(int k,int l,int r)
{tree[k].l=l;tree[k].r=r;tree[k].all=tree[k].ll=tree[k].rr=r-l+1;if(l==r)return;int mid=(l+r)>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);
}void pushup(int k)//注意对三个参数上传的技巧
{tree[k].ll=tree[k<<1].ll;if(tree[k].ll==tree[k<<1].r-tree[k<<1].l+1)tree[k].ll+=tree[k<<1|1].ll;tree[k].rr=tree[k<<1|1].rr;if(tree[k].rr==tree[k<<1|1].r-tree[k<<1|1].l+1)tree[k].rr+=tree[k<<1].rr;tree[k].all=max(tree[k<<1].rr+tree[k<<1|1].ll,max(tree[k<<1].all,tree[k<<1|1].all));return;
}void update(int k,int pos,int val)
{if(tree[k].l==tree[k].r){tree[k].all=tree[k].ll=tree[k].rr=val;return;}int mid=(tree[k].r+tree[k].l)>>1;if(mid>=pos)update(k<<1,pos,val);elseupdate(k<<1|1,pos,val);pushup(k);
}int query(int k,int pos)
{if(tree[k].all==0)return 0;if(tree[k].l+tree[k].ll>pos)//判断是否在左区间 pos<左端点+左连续return tree[k].ll;if(tree[k].r-tree[k].rr<pos)//判断是否在右区间 pos>右端点-右连续 return tree[k].rr;if(pos>tree[k<<1].r-tree[k<<1].rr&&pos<tree[k<<1|1].l+tree[k<<1|1].ll)//判断是否在中间的区间
//右端点-右连续<pos<左端点+左连续return tree[k<<1].rr+tree[k<<1|1].ll;int mid=(tree[k].l+tree[k].r)>>1;if(mid>=pos)//如果上述条件不满足,继续向下递归判断return query(k<<1,pos);elsereturn query(k<<1|1,pos);
}int main()
{
//  freopen("input.txt","r",stdin);int n,m;while(scanf("%d%d",&n,&m)!=EOF){build(1,1,n);stack<int>st;while(m--){char s[5];scanf("%s",s);if(s[0]=='D'){int num;scanf("%d",&num);st.push(num);update(1,num,0);}else if(s[0]=='R'){if(!st.empty()){update(1,st.top(),1);st.pop();}}else{int num;scanf("%d",&num);cout<<query(1,num)<<endl;}}}return 0;
}

HDU - 1540 Tunnel Warfare(线段树+区间合并)相关推荐

  1. hdu 1540 Tunnel Warfare(线段树区间合并)

    hdu 1540 Tunnel Warfare 记录每个节点的最大左连续值.最大右连续值.最大连续值,向上更新的是常规的区间合并处理方式 关键是想到如何去查询,如果查询节点落在左儿子节点的右连续段中, ...

  2. HDU 1540 Tunnel Warfare 线段树区间合并

    Tunnel Warfare 题意:D代表破坏村庄,R代表修复最后被破坏的那个村庄,Q代表询问包括x在内的最大连续区间是多少 思路:一个节点的最大连续区间由(左儿子的最大的连续区间,右儿子的最大连续区 ...

  3. HDOJ1540 - Tunnel Warfare 线段树区间合并

    HDOJ 1540 题目大意:给定两个整数N,M, 其中N表示一共有N个村庄,M代表有M次操作,操作有以下: 1.    D x  销毁村庄x 2.    Q x  询问与村庄x相邻的村庄总数 3.  ...

  4. HDU - 3397 Sequence operation(线段树+区间合并)

    题目链接:点击查看 题目大意:给定一个初始的数列,然后依次进行m次操作: 0 a b:将闭区间[a,b]内的点都变为0 1 a b:将闭区间[a,b]内的点都变为1 2 a b:将闭区间[a,b]内的 ...

  5. HDU - 2871 Memory Control(线段树+区间合并)好题!

    题目链接:点击查看 题目大意:给定n个内存和m个操作,分别是: New x:从内存编号1开始向右查找,分配一个长度为x的空间,若找到输出区间的首地址,否则输出Reject New: Free x:释放 ...

  6. Tunnel Warfare(HDU1540+线段树+区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1540 题目: 题意:总共有n个村庄,有q次操作,每次操作分为摧毁一座村庄,修复一座村庄,和查询与询问的 ...

  7. HDU3308 线段树区间合并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 ,简单的线段树区间合并. 线段树的区间合并:一般是要求求最长连续区间,在PushUp()函数中实 ...

  8. 树链剖分——线段树区间合并bzoj染色

    线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...

  9. SPOJ GSS3-Can you answer these queries III-分治+线段树区间合并

    Can you answer these queries III SPOJ - GSS3 这道题和洛谷的小白逛公园一样的题目. 传送门: 洛谷 P4513 小白逛公园-区间最大子段和-分治+线段树区间 ...

最新文章

  1. 38.linux集合
  2. dyld: Library not loaded: @rpath/XCTest.framework/XCTest
  3. oracle 数字不用,oracle – Plsql将数字(货币)拼写为意大利货币而不用硬编码的翻译编号...
  4. mysql日期格式化季度_mysql中常用日期比较与计算函数
  5. 程序人生:给年轻程序员关于开发过程的10条忠告
  6. Gradle插件学习笔记(二)
  7. php redius,Linux下Redius的安装与部署详解
  8. 前端学到什么水平就可以去找工作呢?
  9. Hibernate之ID生成规则
  10. 一个 JS 框架需要做什么
  11. restController
  12. POJ1061 青蛙的约会 扩展欧几里得
  13. i510400和i59400f哪个好?有什么区别
  14. linux常用的解压缩文件的命令
  15. 细胞生物学-7-叶绿体和线粒体
  16. ARM发布Cortex-X1,是为了向苹果自研A系列处理器发起冲击吗?
  17. JavaScript: JSON基本概念带题解
  18. PhotoScan:为冲印的照片拍摄无眩光照片
  19. 关于Docker以及安装方法
  20. 偶像和粉丝关系该是什么样的?

热门文章

  1. parkAndCheckInterrupt
  2. 分布式架构的session问题
  3. 模拟springIOC容器的annotation
  4. request的其他细节
  5. 文件上传之传统方式上传代码回顾
  6. 文件操作-打开文件方式以及写入和追加数据
  7. Eureka集群部署
  8. xxl-job 2.1.1执行器源码解读
  9. C语言创建指针需要给大小吗,如何用c语言创建一个指针(示例代码)
  10. java观察者模式在spring中的应用_Spring源码之spring中的观察者模式和监听器的使用...