kuangbin——线段树专题 H - Tunnel Warfare
来源:互联网 发布:mac 相对于卷宗的格式 编辑:程序博客网 时间:2024/06/05 19:44
大体思路比较简单,就是利用线段数求区间
最大和最小值。
这里假设其为 1 2 3 4 5 6 7
则如果 其中有若干个村子被毁了,如果要求第4个村子
只需求出来 1->4区间中被毁村子的最大值(2),
和 4->7 区间中被毁村子的最小值(5),
根据两者求出村子的连续区间,即 2->5 所以其村子连续个数 为 5-2-1 = 2
即minn - maxx -1
特殊情况: 如果1 2 3 4 5 6 7 求2的连续区间 ,其最大为2,最小也为2
则其连续个数为 0
思路出来了,这里就借助线段树,来求区间的最大值和最小值。
这里注意,对于没有被摧毁的村子,不加入到线段数节点,而是分别用
0(求最大值时)和n+1(求最小值时)代替,这样能保证,其不影响加入村子的求极值
而且最其在没有村子被摧毁的情况下,也能正确的求出解。
例子: 1 2 3 4 5 6 7
求村子3的连续区间,这里1->3 maxx为0 ; 3->n minn为4
所以其连续空间为4-0-1 =3 为正解
可以自己再试其他例子
到这里,线段树就构造好了
求区间最大最小值,直接套线段树模板就好。
下面直接上代码:
#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>#include <algorithm>#define INF 0x3f3f3f3fusing namespace std;typedef long long ll;#define M 50015#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef struct SegTreeNode{ int maxx; int minn;}segtree; //线段树结构体,一个用来求最大值,一个用来求最小值segtree arr[M<<2];int n;int history[M<<2];//保存历史,用于Rvoid build(int l,int r,int rt)//建树{ if(l == r){ arr[rt].minn = n+1; arr[rt].maxx = 0; return; } int m = (l+r)>>1; build(lson); build(rson); arr[rt].maxx = max(arr[rt<<1].maxx,arr[rt<<1|1].maxx); arr[rt].minn = min(arr[rt<<1].minn,arr[rt<<1|1].minn);}void update_maxx(int p,int sc,int l,int r ,int rt)//更新求最大值的线段树{ if(l == r) { arr[rt].maxx = sc; return ; } int m = (l+r)>>1; if(p<=m) update_maxx(p,sc,lson); else update_maxx(p,sc,rson); arr[rt].maxx = max(arr[rt<<1].maxx,arr[rt<<1|1].maxx);}void update_minn(int p,int sc,int l,int r ,int rt)//更新求最小值的线段树{ if(l == r) { arr[rt].minn = sc; return ; } int m = (l+r)>>1; if(p<=m) update_minn(p,sc,lson); else update_minn(p,sc,rson); arr[rt].minn = min(arr[rt<<1].minn,arr[rt<<1|1].minn);}int query_minn(int L,int R,int l,int r ,int rt) //查找区间最小值{ if(L<=l && r<=R) { return arr[rt].minn; } int m = (l + r) >>1; int ret = INF; if(L<=m) ret = min(ret,query_minn(L,R,lson)); if(R>m) ret = min(ret,query_minn(L,R,rson)); return ret;}int query_maxx(int L,int R,int l,int r ,int rt) //查找区间最大值{ if(L<=l && r<=R) { return arr[rt].maxx; } int m = (l + r) >>1; int ret = 0; if(L<=m) ret = max(ret,query_maxx(L,R,lson)); if(R>m) ret = max(ret,query_maxx(L,R,rson)); return ret;}int main(int argc, char const *argv[]){int m,a,temp,count;char ch[10];while(scanf("%d %d",&n,&m) == 2){ count = 0; //历史计算器 memset(history,0,sizeof(history)); memset(arr,0,sizeof(arr)); build(1,n,1);while(m--){scanf("%s",ch);if(ch[0] == 'D') { scanf("%d",&a);update_minn(a,a,1,n,1);//更新线段数的值,把a对应的值更新成aupdate_maxx(a,a,1,n,1);history[++count] = a; //存储到历史记录中}else if(ch[0] == 'Q'){int re,max1,min1; scanf("%d",&a);max1=query_maxx(1,a,1,n,1);//根据线段树查询min1=query_minn(a,n,1,n,1); if(max1 == min1) //考虑特殊情况printf("%d\n",0);else printf("%d\n",min1-max1-1);}else { temp = history[count--]; update_minn(temp,n+1,1,n,1); //如果恢复,就把对应的值改为0或n+1 update_maxx(temp,0,1,n,1); }} }return 0;}
poj 题目链接:http://poj.org/problem?id=2892
0 0
- kuangbin——线段树专题 H - Tunnel Warfare
- nbut线段树专题Q - Tunnel Warfare
- HDU_1540 Tunnel Warfare 线段树
- hdu Tunnel Warfare(线段树)
- poj2892--Tunnel Warfare(线段树)
- Tunnel Warfare(线段树)
- HDU 1540——Tunnel Warfare(线段树,区间合并+单点更新+单点查询)
- hdu 1540 Tunnel Warfare(线段树——单点更新+区间合并)
- HDU 1540 Tunnel Warfare——特殊查询的线段树
- HDOJ 1540 Tunnel Warfare(线段树)
- POJ2892地道战Tunnel Warfare(线段树)
- hdu1540 Tunnel Warfare 线段树中等难题
- hdu 1540 Tunnel Warfare 线段树
- poj 2892 Tunnel Warfare(线段树)
- HDU1540:Tunnel Warfare(线段树区间合并)
- hdu-1540-Tunnel Warfare-线段树
- 【HDU】 1540 Tunnel Warfare 线段树
- POJ-2892-Tunnel Warfare(线段树)
- CSS实现圆角,三角,五角星,五边形,爱心,12角星,8角星,圆,椭圆,圆圈,八卦
- 淘淘商城项目---8.5
- 大数据DTSpark"蘑菇云"行动之 第二课:Scala初体验
- 2044--一只小蜜蜂
- 移动WebKit
- kuangbin——线段树专题 H - Tunnel Warfare
- Android 自定义ListView
- Activity启动清空原任务栈
- javaScript笔记(十) 基本包装类型
- 安卓开发之封装显示倒计时按钮控件
- MP4(三)-复用器,数据的存储
- java源码:HashMap实现原理
- 【Leetcode】之Symmetric Tree
- PAT (Basic Level) Practise-1041