poj 2892 线段树 区间合并
来源:互联网 发布:linux 中断ping 编辑:程序博客网 时间:2024/05/22 23:27
题目:http://poj.org/problem?id=2892
线段树也做了不知一个了。。。。感觉自己写线段树的水平真不怎么给力。。。。。。。。。。。。。。。。。
我这个脑子哎。。。貌似,我线段树啥时候能够给力些,在给力些呢。。。。
/*题意:给出直线上一系列的村庄,如果相邻村庄都没有被破坏,则两村庄是连接的,题目给出一系列的破坏操作,对指定号码的村庄进行破坏,还有一系列的询问操作,询问与指定号码的村庄直接相连或间接相连的村庄有几个,还有一个修复操作,是对最后破坏的村庄进行修复。定义三个变量:lmax[rt] 表示从左孩子开始的连续区间个数 rmax[rt] 到右孩子截至的连续区间个数 mmax[rt] 整个区间连续的区间个数 col[rt] 表示区间的状态,0表示未必破坏,1表示已被破坏,-1初始状态因为为连续区间关键步骤是pushdown 里的赋值操作和pushup的更新操作*/#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=50002;int lmax[maxn<<2],rmax[maxn<<2],mmax[maxn<<2],col[maxn<<2],vis[maxn<<2],s[maxn],n,m;#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,rchar op[2];void pushup(int rt,int l,int r){ int mid=(l+r)>>1; lmax[rt]=lmax[rt<<1]; rmax[rt]=rmax[rt<<1|1]; mmax[rt]=max(mmax[rt<<1],mmax[rt<<1|1]); if(lmax[rt<<1]==mid-l+1) { lmax[rt]+=lmax[rt<<1|1]; } if(rmax[rt<<1|1]==r-mid) { rmax[rt]+=rmax[rt<<1]; } mmax[rt]=max(mmax[rt],rmax[rt<<1]+lmax[rt<<1|1]);}void pushdown(int rt,int l,int r){ int mid=(l+r)>>1; if(col[rt]!=-1) { col[rt<<1]=col[rt<<1|1]=col[rt]; if(col[rt]==1) { lmax[rt<<1]=rmax[rt<<1]=mmax[rt<<1]=0; lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1|1]=0; } else { lmax[rt<<1]=rmax[rt<<1]=mmax[rt<<1]=mid-l+1; lmax[rt<<1|1]=rmax[rt<<1|1]=mmax[rt<<1|1]=r-mid; } col[rt]=-1; }}void build(int rt,int l,int r){ lmax[rt]=rmax[rt]=mmax[rt]=r-l+1; col[rt]=-1; if(l==r) { return; } int mid=(l+r)>>1; build(lson); build(rson);}void updata(int rt,int l,int r,int idx,int val){ if(l==r) { col[rt]=val; lmax[rt]=rmax[rt]=mmax[rt]=(val?0:r-l+1); return; } pushdown(rt,l,r); int mid=(l+r)>>1; if(mid>=idx)updata(lson,idx,val); else updata(rson,idx,val); pushup(rt,l,r);}int query(int rt,int l,int r,int idx){ if(l==r||mmax[rt]==(r-l+1)||!mmax[rt]) { return mmax[rt]; } int mid=(l+r)>>1; if(mid>=idx) { if(idx>=mid-rmax[rt<<1]+1) return lmax[rt<<1|1]+rmax[rt<<1]; return query(lson,idx); } else { if(idx<=mid+lmax[rt<<1|1]+1) return lmax[rt<<1|1]+rmax[rt<<1]; return query(rson,idx); }}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { int i,j,idx,st=0; build(1,1,n); memset(vis,0,sizeof(vis)); for(i=1; i<=m; i++) { scanf("%s",&op); if(op[0]=='D') { scanf("%d",&idx); updata(1,1,n,idx,1); s[st++]=idx; vis[idx]=1; } else if(op[0]=='Q') { scanf("%d",&idx); printf("%d\n",vis[idx]?0:query(1,1,n,idx)); } else { if(st>0) { updata(1,1,n,s[--st],0); vis[s[st]]=0; } } } } return 0;}/*7 9D 3D 6D 5Q 4Q 5RQ 4RQ 4*/
- poj 2892 线段树 区间合并
- poj 3667 区间合并 区间线段树
- POJ 2892 Tunnel Warfare 区间合并线段树
- POJ--2892--Tunnel Warfare【线段树】区间合并
- hdu 1540 & poj 2892 Tunnel Warfare 线段树区间合并
- HDU 1540 POJ 2892 线段树区间合并
- hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】
- POJ -2892 Tunnel Warfare - 线段树区间合并
- poj 3667【线段树-区间合并】
- POJ 3667 Hotel 线段树区间合并
- poj 3667 Hotel 线段树区间合并
- poj 3667 线段树 区间合并
- POJ 3667 Hotel 线段树 区间合并
- poj 3667 线段树合并区间
- Poj 3667 Hotel 线段树 区间合并
- POJ Hotel 线段树 区间合并
- POJ 3667-hotel(线段树区间合并)
- poj 3667 线段树,区间合并
- Linux 进程间通信 - 共享内存shmget方式(转)
- ZOJ 3657 The Little Girl who Picks Mushrooms(12年长春区域赛-C题-枚举)
- vim列模式编辑方法
- C++的犄角旮旯
- C/C++变量在内存中的分布
- poj 2892 线段树 区间合并
- 剖析程序的内存布局
- 润乾参数模板的使用
- 各个语言垃圾回收机制汇总(C++)
- 时间2
- 二战狙击手排名
- 为什么要使用 JavaScript
- 时间3
- 连接管理相关命令