HDU-1540 Tunnel Warfare 线段树 区间合并
来源:互联网 发布:java文章管理系统 编辑:程序博客网 时间:2024/05/21 06:19
http://acm.hdu.edu.cn/showproblem.php?pid=1540
题意:
给出直线上一系列的村庄,如果相邻村庄都没有被破坏,
则两村庄是连接的,题目给出一系列的破坏操作,对指定号码的村庄进行破坏,
还有一系列的询问操作,询问与指定号码的村庄直接相连或间接相连的村庄有几个,
还有一个修复操作,是对最后破坏的村庄进行修复。
//线段树
定义三个变量:lmax[rt] 表示从左孩子开始的连续区间个数
rmax[rt] 到右孩子截至的连续区间个数
mmax[rt] 整个区间连续的区间个数
col[rt] 表示区间的状态,0表示未必破坏,1表示已被破坏,-1初始状态
因为为连续区间关键步骤是pushdown 里的赋值操作和pushup的更新操作
#include "stdio.h"#include "string.h"const int maxn = 50005;int n,q,x,val;int stack[maxn],top;bool vis[maxn];struct node { int col; //表示区间的状态,0表示未必破坏,1表示已被破坏,-1初始状态 int rmax,lmax,mmax; //到右孩子截至的连续区间个数 表示从左孩子开始的连续区间个数 整个区间连续的区间个数 }tree[maxn*4];int Max( int a,int b ){ return a>=b?a:b;}void pushup( int ld,int rd,int t ){ int mid = ( ld+rd )>>1; tree[t].lmax = tree[t<<1].lmax; tree[t].rmax = tree[t<<1|1].rmax; tree[t].mmax = Max( tree[t<<1].mmax,tree[t<<1|1].mmax ); if( tree[t<<1].lmax == mid - ld +1 ) { tree[t].lmax += tree[t<<1|1].lmax; } if( tree[t<<1|1].rmax == rd - mid ) { tree[t].rmax += tree[t<<1].rmax; } tree[t].mmax = Max( tree[t].mmax,tree[t<<1].rmax+tree[t<<1|1].lmax);}void pushdown( int ld,int rd,int t ){ if( tree[t].col!=-1 ) { int mid = ( ld+rd )>>1; tree[t<<1].col = tree[t<<1|1].col =tree[t].col; if( tree[t].col==1 ) { tree[t<<1].lmax = tree[t<<1].rmax = tree[t<<1].mmax = 0; tree[t<<1|1].lmax = tree[t<<1|1].rmax = tree[t<<1|1].mmax = 0; } else { tree[t<<1].lmax = tree[t<<1].rmax = tree[t<<1].mmax = mid-ld+1; tree[t<<1|1].lmax = tree[t<<1|1].rmax = tree[t<<1|1].mmax = rd-mid; } tree[t].col = -1; }}void buildtree( int ld,int rd,int t ){ tree[t].col = -1; tree[t].rmax = tree[t].lmax = tree[t].mmax = rd-ld+1; if( ld == rd ) return; int mid = ( ld+rd )>>1; buildtree( ld,mid,t<<1 ); buildtree( mid+1,rd,t<<1|1 );}void updata( int ld,int rd,int t ){ if( ld == rd ) { tree[t].col = val; tree[t].lmax = tree[t].rmax = tree[t].mmax = ( val?0:1 ); return; } pushdown( ld,rd,t ); int mid = ( ld+rd )>>1; if( x<=mid ) updata( ld,mid,t<<1 ); else updata( mid+1,rd,t<<1|1 ); pushup( ld,rd,t );}int query( int ld,int rd,int t ){ if( ld == rd || tree[t].mmax==( rd-ld+1 ) || !tree[t].mmax ) { return tree[t].mmax; } int mid = ( ld+rd )>>1; if( x<=mid ) { if( x >= mid - tree[t<<1].rmax+1 ) return tree[t<<1].rmax + tree[t<<1|1].lmax; else return query( ld,mid,t<<1 ); } else { if( x <= mid + tree[t<<1|1].lmax+1 ) return tree[t<<1].rmax + tree[t<<1|1].lmax; else return query( mid+1,rd,t<<1|1 ); }}int main(){ int i; char ch[3]; while( scanf("%d%d",&n,&q)==2 ) { top = 0; memset(vis,0,sizeof(vis)); getchar(); buildtree( 1,n,1 ); for( i=1;i<=q;i++ ) { scanf("%s",ch); if( ch[0]=='D' ) { scanf("%d",&x); stack[++top] = x; val = 1;//1为摧毁 if( !vis[x] ) updata(1,n,1); vis[x] = 1; } else if( ch[0]=='Q' ) { scanf("%d",&x); printf("%d\n",vis[x]?0:query(1,n,1) ); } else { if( top ) { x = stack[top--]; val = 0;//0为修复 if( vis[x] ) updata( 1,n,1 ); vis[x] = 0; } } } } return 0;}
- HDU-1540 Tunnel Warfare 线段树 区间合并
- hdu 1540 Tunnel Warfare(线段树区间合并)
- hdu 1540 & poj 2892 Tunnel Warfare 线段树区间合并
- 【Hdu】1540 Tunnel Warfare(线段树|区间合并)
- HDU 1540 Tunnel Warfare(线段树 区间合并 +单点更新)
- hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】
- HDU 1540 Tunnel Warfare(线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树区间合并)
- HDU - 1540 Tunnel Warfare(线段树 区间合并)
- hdu 1540 Tunnel Warfare (线段树区间合并)
- hdu 1540 Tunnel Warfare 【线段树 区间合并】
- HDU 1540 Tunnel Warfare 线段树区间合并
- HDU 1540 Tunnel Warfare(线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树,区间合并)
- HDU-1540 Tunnel Warfare (线段树区间合并)
- Hdu 1540 Tunnel Warfare【线段树区间合并学习】
- HDU 1540 Tunnel Warfare 线段树区间合并
- HDU 1540Tunnel Warfare Tunnel Warfare (线段树- 区间合并-单点更新查询)
- mysq性能优化,摘下来慢慢看
- javascript与DOM(文档对象模型)
- Redmine使用——Redmine项目管理系统工作逻辑
- Struts2 i18n国际化(允许用户自行选择语言)
- XE5技巧
- HDU-1540 Tunnel Warfare 线段树 区间合并
- 【系统】注册表分析
- 如家汉庭开房门教你学习sql server数据库还原
- jquery 的显示隐藏效果 .slideToggle()
- 第八周上机实践
- 数组指针 和 指针数组
- linux 内核源代码 目录结构 介绍
- C语言中二维数组做参数的使用小结
- 一些开发有用的连接