HDU 1540 Tunnel Warfare (线段树)
2015-08-27 10:58
211 查看
题目大意: n 个村庄排列在一条直线上,相邻的村庄有地道连接,除首尾两个村庄外,其余村庄都有两个相邻的村庄。其中有 3 中操作 D x :表示摧毁编号为 x 的村庄,Q x:表示求出包含村庄 x 的最长区间中村庄的数目,R 表示修复最后摧毁的村庄。输入 n,m 分别表示村庄的树木,和操作的次数。
思路 : 当查询包含 村庄 x 的最长区间的村庄数时,可以求出位于 区间 [1,x-1] 中被摧毁的最大村庄编号,求出[x+1,n] 中被摧毁的最小村庄的编号。由此便可求出结果。
可利用线段树存储区间内的被摧毁的村庄的最大和最小编号。
代码:
思路 : 当查询包含 村庄 x 的最长区间的村庄数时,可以求出位于 区间 [1,x-1] 中被摧毁的最大村庄编号,求出[x+1,n] 中被摧毁的最小村庄的编号。由此便可求出结果。
可利用线段树存储区间内的被摧毁的村庄的最大和最小编号。
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<queue> #include<algorithm> #include<cmath> #include<map> using namespace std; #define INF 100000000 int n,m; struct node{ int l; int r; int MAX; int MIN; }a[201000]; void buildtree(int i,int l,int r){ a[i].l = l ; a[i].r = r ; a[i].MAX = -INF ; a[i].MIN = INF ; if(l == r) return ; int mid = (l+r)/2; buildtree(i*2,l,mid); buildtree(i*2+1,mid+1,r); } void Destory(int i,int x){ a[i].MAX = max(a[i].MAX,x); a[i].MIN = min(a[i].MIN,x); if(a[i].l == a[i].r) return ; int mid = (a[i].l + a[i].r) / 2; if(x <= mid) Destory(i*2,x); else Destory(i*2+1,x); } int Querymax(int i,int l,int r){ if(a[i].l == l && a[i].r == r){ return a[i].MAX ; } if(a[i].l == a[i].r) return a[i].MAX; int ans = -INF; int mid = (a[i].l + a[i].r) / 2 ; if(r <= mid) ans = Querymax(i*2,l,r); else if(l > mid) ans = Querymax(i*2+1,l,r); else{ ans = max(ans,Querymax(i*2,l,mid)); ans = max(ans,Querymax(i*2+1,mid+1,r)); } return ans ; } int Querymin(int i,int l,int r){ if(a[i].l == l && a[i].r == r) return a[i].MIN ; if(a[i].l == a[i].r) return a[i].MIN; int ans = INF ; int mid = (a[i].l + a[i].r) / 2 ; if(r <= mid) ans = Querymin(i*2,l,r) ; else if(l > mid) ans = Querymin(i*2+1,l,r) ; else{ ans = min(ans,Querymin(i*2,l,mid)); ans = min(ans,Querymin(i*2+1,mid+1,r)); } return ans ; } void rebuild(int i,int x){ if(a[i].l == a[i].r){ a[i].MAX = -INF ; a[i].MIN = INF ; return ; } int mid = (a[i].l + a[i].r) / 2 ; if(x <= mid) rebuild(i*2,x); else rebuild(i*2+1,x); a[i].MAX = max(a[i*2].MAX,a[i*2+1].MAX); a[i].MIN = min(a[i*2].MIN,a[i*2+1].MIN); } int main(){ char op; int x,sum,top,stack[50000]; while(~scanf("%d%d",&n,&m)){ buildtree(1,1,n); top = 0; for(int k=1;k<=m;k++){ getchar(); scanf("%c",&op) ; if(op == 'D'){ scanf("%d",&x); stack[top++] = x ; Destory(1,x); } else if(op == 'Q'){ scanf("%d",&x); int ans1 = Querymax(1,1,x); int ans2 = Querymin(1,x,n); if(ans1==x || ans2==x) printf("0\n"); else { if(ans1 == -INF) sum = x - 1 ; else sum = x - ans1 - 1 ; if(ans2 == INF) sum += n - x ; else sum += ans2 - 1 - x; sum ++ ; printf("%d\n",sum); } } else if(op == 'R'){ if(top > 0) rebuild(1,stack[--top]); } } } return 0; }
相关文章推荐
- 计算机视觉---4.2---几何不变量
- hudson的过程
- android静态库链接顺序问题
- OC基础回顾(十四)文件加载与保存
- CDH5.4.5离线分布式安装,角色及目录参考
- 烟草行业卷烟厂综合布线系统简析
- ubuntu上开启SNMP服务
- JAVA问题总结之15-多个类之间的调用
- Opencv的merge函数-通道合并
- 线程中CreateEvent和SetEvent及WaitForSingleObject的用法
- 获取当前视图所在控制器
- 竖直展开菜单
- 按照与字母v的距离排序,距离小的在前面。(华为2016)
- Mac系统新建txt文本文件技巧
- ionic开发android App
- HDUOJ_2023(求平均成绩)
- kafka无法发送消息问题处理
- JAX-RS @Path URI matching example
- Java利用Http模拟表单提交
- 异常——Caused by: java.sql.SQLException: ORA-00911: 无效字符