Tunnel Warfare (区间合并)
来源:互联网 发布:retrofit 传json 编辑:程序博客网 时间:2024/05/01 16:59
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!
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.
7 9D 3D 6D 5Q 4Q 5RQ 4RQ 4
1024
这就是传说中的区间合并,感觉不到区间合并,只是一种找区间的感觉,还是一个人有一个人的管辖范围。
#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<stack>#define INF 0x3f3f3f3f#define lson(x) (x<<1)#define rson(x) (x<<1|1)#define ml(x,y) ((x+y)>>1)#define lowbit(x) (x&(-x))using namespace std;typedef long long ll;const int maxn=5e4+10;/*这道题给我的感觉就是,树还是一样的建造。但是我们存储了三个值ls ,ms,rs;分别代表什么意思呢左儿子管辖范围内从最左面第一个没有被炸的点 开始的连续长度值;右儿子管辖范围内从最右面第一个没有被炸的点 开始的连续长度值;ms什么意思呢,就是说当爹的管辖范围内最长的连续线段长度,感觉主要是为了方便判断,是不是满树,空树;就是说除了左右儿子分的这么清楚的,是不是还有一段可以横跨爹给画的界限的线段诺,就是tree[lson(nid)].rs+tree[rson(nid)].ls,那他们的目的是什么呢,主要就是合并的问题,可以直接判断合并到什么程度。*/int n;struct node{ int l,r; int ls,ms,rs;}tree[maxn*4];void build(int st,int ed,int nid){ tree[nid].l=st; tree[nid].r=ed; tree[nid].ls=tree[nid].ms=tree[nid].rs=ed-st+1;//先都是满树 if(st==ed) return; int mid=ml(st,ed); build(st,mid,lson(nid)); build(mid+1,ed,rson(nid));}void update(int nid,int num,int val){ if(tree[nid].l==tree[nid].r)//说明这是单点,首先明白我们是点更新,一定是更新到点的,只不过回去的时候做了个标记 { tree[nid].ls=tree[nid].ms=tree[nid].rs=val;//找到单点,对其更新,该连的连,该断的断 return; } int mid=ml(tree[nid].l,tree[nid].r); if(num<=mid) update(lson(nid),num,val);//这是去找人(点) else update(rson(nid),num,val);/*我们是先往下找,因为我们不知道下面是什么情况,只有他反馈回来,我们才知道下面子孙的情况*/ if(tree[lson(nid)].ms==tree[lson(nid)].r-tree[lson(nid)].l+1)//左子树满了,也就是说,左边儿子的管辖区域内都是连通的 tree[nid].ls=tree[lson(nid)].ms+tree[rson(nid)].ls;//这样的话,爹的左连续区间应该是 左+右儿子的区间内 和左儿子相连的 else tree[nid].ls=tree[lson(nid)].ls;//要不然的话,当爹的左连续区间只能是,左儿子的左连续区间,也就是说当爹的管辖范围内,最左面那条线段了 if(tree[rson(nid)].ms==tree[rson(nid)].r-tree[rson(nid)].l+1)//同理 tree[nid].rs=tree[rson(nid)].ms+tree[lson(nid)].rs; else tree[nid].rs=tree[rson(nid)].rs; tree[nid].ms=max(max(tree[lson(nid)].ms,tree[rson(nid)].ms),tree[lson(nid)].rs+tree[rson(nid)].ls);}int query(int nid,int num){ if(tree[nid].l==tree[nid].r||tree[nid].ms==0||tree[nid].ms==tree[nid].r-tree[nid].l+1)//到了叶子,空树,满树 return tree[nid].ms;//可以直接返回了,因为他问的是区间,而你那个点正好就在这个区间内,然而这三种情况就可以直接判断了 int mid=ml(tree[nid].l,tree[nid].r); if(num<=mid) { if(num<tree[lson(nid)].r-tree[lson(nid)].rs+1)//说明不在左儿子管辖区间内的最右右连续的线段上 return query(lson(nid),num);//那我们就得继续往下查找 else//否则,就说明它在左儿子和右儿子的范围内的那条线段上 return tree[lson(nid)].rs+tree[rson(nid)].ls;//我们就返回这个骑着的区间值 } else//同理 { if(num>tree[rson(nid)].l+tree[rson(nid)].ls-1) return query(rson(nid),num); else return tree[lson(nid)].rs+tree[rson(nid)].ls; }}int main(){ int m; while(~scanf("%d %d",&n,&m)) { stack<int> stk; build(1,n,1); while(m--) { char str; int temp; scanf(" %c",&str); if(str=='D') { scanf("%d",&temp); stk.push(temp); update(1,temp,0);//从根进去,temp,损伤 } else if(str=='Q') { scanf("%d",&temp); printf("%d\n",query(1,temp));//从根进去,查询temp } else { temp=stk.top(); stk.pop(); update(1,temp,1);//从根进去,temp,修复 } } } return 0;}
阅读全文
0 0
- Tunnel Warfare (区间合并)
- HDU 1540 Tunnel Warfare(区间合并)
- hdu 1540 Tunnel Warfare(区间合并)
- HDU 1540Tunnel Warfare 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(单点更新,区间合并)
- hdu1540 Tunnel Warfare(线段树区间合并详解)
- HDOJ 1540 Tunnel Warfare (线段树+区间合并)
- HDOJ 1540 Tunnel Warfare (线段树之区间合并)
- HDU1540-Tunnel Warfare(线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树,区间合并)
- HDU-1540 Tunnel Warfare (线段树区间合并)
- HDU1540:Tunnel Warfare(线段树区间合并)
- hdu1540 Tunnel Warfare 线段树区间合并
- JAVA 中 Redis与ehcache对比与使用
- java.util.ArrayDeque源码解析
- 把冷话加热了再说
- UVA 562 Dividing coins(01背包)
- 将N个字符的数组,循环右移K位。时间复杂度O(N)。
- Tunnel Warfare (区间合并)
- lambda表达式
- pat:L1-031. 到底是不是太胖了
- AJAX(XMLHttpRequest.status)状态码
- 新人报道
- 字节流与字符流
- AngualrJS(四)input元素的ng-model属性
- 关于androidstudio突然没有提示的问题
- 提高sqlmap爆破效率