线段树--区间合并hdu--1540
来源:互联网 发布:linux mkdir函数 编辑:程序博客网 时间:2024/05/18 16:55
Tunnel Warfare
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8569 Accepted Submission(s): 3301
Problem Description
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly connected with two neighboring ones.
Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration of connection must be done immediately!
Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration of connection must be done immediately!
Input
The first line of the input contains two positive integers n and m (n, m ≤ 50,000) indicating the number of villages and events. Each of the next m lines describes an event.
There are three different events described in different format shown below:
D x: The x-th village was destroyed.
Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.
R: The village destroyed last was rebuilt.
There are three different events described in different format shown below:
D x: The x-th village was destroyed.
Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.
R: The village destroyed last was rebuilt.
Output
Output the answer to each of the Army commanders’ request in order on a separate line.
Sample Input
7 9D 3D 6D 5Q 4Q 5RQ 4RQ 4
Sample Output
1024
线段树本就擅长于处理区间问题,这题思考很久之后,我想到了做法,最开始整个区间是连续的,当破坏了一个村庄之后,当前区间的从左数和从右数的连续区间要更新,L数组用来存当前区间从左数最长区间,R数组用来存当前区间从右到左最长连续区间,S数组是当前区间最大连续区间,lc和rc是端点的区间。而这道题是单点更新,不需要标记,只要往上更新就行了
#include <iostream>#include <stdio.h>#include <string.h>#define siz 50005#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)|1)using namespace std;int sets[siz<<2],lc[siz<<2],rc[siz<<2];int L[siz<<2],R[siz<<2],S[siz<<2];int n,m;int sta[siz];int length(int root){ return rc[root]-lc[root]+1;}void maintain(int root,int v){ L[root]=R[root]=S[root]=(v?length(root):0);///当前状态当前区间更新为有空房间和无空房间}void pushup(int root){ S[root]=max(max(S[lson(root)],S[rson(root)]),R[lson(root)]+L[rson(root)]); L[root]=L[lson(root)]+(L[lson(root)]==length(lson(root))?L[rson(root)]:0); ///如果左儿子全是连续区间,则当前区间右儿子从左数的连续区间是从左边数的连续区间的一部分 R[root]=R[rson(root)]+(R[rson(root)]==length(rson(root))?R[lson(root)]:0); ///同理}void build(int root,int l,int r){ lc[root]=l; rc[root]=r; if(l==r){ maintain(root,1);///建树,1代表整个区间连续 return ; } int mid=(lc[root]+rc[root])>>1; build(lson(root),l,mid); build(rson(root),mid+1,r); pushup(root);}void modify(int u,int k,int v){///类似于普通线段树的单点更新 //cout<<u<<" "<<k<<"^^^"<<lc[u]<<endl; if(lc[u]==rc[u]&&lc[u]==k){ maintain(u,v); return ; } int mid=(lc[u]+rc[u])>>1; //cout<<mid<<" "<<lc[u]<<" "<<rc[u]<<endl; if(k<=mid) modify(lson(u),k,v); else modify(rson(u),k,v); pushup(u);}int query(int rt,int k){ if(lc[rt]==rc[rt]&&lc[rt]==k){ return S[rt]; } int mid=(lc[rt]+rc[rt])>>1; if(k<=mid){ if(mid-R[lson(rt)]+1<=k){///最左边比k小,说明k在从右数连续区间内 return R[lson(rt)]+L[rson(rt)];///加上左边的区间 }else{ return query(lson(rt),k); } }else{ if(mid+1+L[rson(rt)]-1>=k){///同理 return L[rson(rt)]+R[lson(rt)]; }else{ return query(rson(rt),k); } }}int main(){ while(~scanf("%d%d",&n,&m)){ build(1,1,n); int ind=0; while(m--){ //getchar(); char c[2]; int v; scanf("%s",c); if(c[0]=='D'){ scanf("%d",&v); sta[ind++]=v; modify(1,v,0);///村庄被销毁,断点 } else if(c[0]=='Q'){ scanf("%d",&v); int ans=query(1,v); printf("%d\n",ans); } else{ if(ind>0){ v=sta[--ind]; modify(1,v,1);///1修复村庄 } } // cout<<1<<endl; } } return 0;}
0 0
- hdu 1540 线段树区间合并
- hdu 1540 线段树+区间合并
- hdu 1540 线段树区间合并
- 线段树--区间合并--HDU 1540
- HDU 1540 线段树区间合并
- hdu 1540 线段树(区间合并入门)
- 线段树--区间合并hdu--1540
- HDU-1540 Tunnel Warfare 线段树 区间合并
- hdu 1540 Tunnel Warfare(线段树区间合并)
- hdu 1540 & poj 2892 Tunnel Warfare 线段树区间合并
- HDU 1540 POJ 2892 线段树区间合并
- 【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 (线段树区间合并)
- 基于TV模型的image inpainting算法
- 全排列延伸编程题目
- HttpCallUtil
- 发现一个不错的博客
- 第三章:字符串、向量和数组
- 线段树--区间合并hdu--1540
- JavaScript的执行上下文(与上下文不同,此点常被混淆)
- 人脸检测中误检漏检
- 四种控制事务的方法
- java中类的加载顺序
- 点击增加输入框,可删除,类似投票选项增加
- hive jdbc连接
- x265-2.4版本编译问题 error C2668: “pow”: 对重载函数的调用不明确
- 【Android】CameraUtil