poj2892,线段树单点更新,区间合并
来源:互联网 发布:手机淘宝怎么举报假货 编辑:程序博客网 时间:2024/05/16 18:51
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!
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.
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
Hint
An illustration of the sample input: OOOOOOOD 3 OOXOOOOD 6 OOXOOXOD 5 OOXOXXOR OOXOOXOR OOXOOOO
线段树做法:
#include <cstdio>#include <cstring>#include <stack>#include <iostream>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn=50009;//lsum为以区间左端点为起始点的最长连续长度//rsum为以区间右端点为终点的最长连续长度//msum为整个区间的最长连续长度int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2];int n,m;char op[10];void pushup(int rt,int l,int r){ lsum[rt]=lsum[rt<<1]; rsum[rt]=rsum[rt<<1|1]; msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]); int m=l+r>>1; //区间合并 if(msum[rt<<1]==m-l+1) lsum[rt]+=lsum[rt<<1|1]; if(msum[rt<<1|1]==r-(m+1)+1) rsum[rt]+=rsum[rt<<1];}void build(int l,int r,int rt){ lsum[rt]=rsum[rt]=msum[rt]=r-l+1; if(l==r) return; int m=l+r>>1; build(lson); build(rson);}void update(int pos,int val,int l,int r,int rt){ if(l==r) { lsum[rt]=rsum[rt]=msum[rt]=val; return; } int m=l+r>>1; if(pos<=m) update(pos,val,lson); else update(pos,val,rson); pushup(rt,l,r);}int query(int pos,int l,int r,int rt){ if(msum[rt]==r-l+1||msum[rt]==0||l==r) return msum[rt]; int m=l+r>>1; int ret; if(pos<=m) { //如果查询点在左儿子区间,并且在左儿子区间的右端点最长连续范围内//那么就有可能存在右儿子区间中与其连续的段 if(pos>=m-rsum[rt<<1]+1) ret=query(pos,lson)+query(m+1,rson); else ret=query(pos,lson); } else { if(pos<=m+1+lsum[rt<<1|1]-1) ret=query(pos,rson)+query(m,lson); else ret=query(pos,rson); } return ret;}int main(){ while(scanf("%d%d",&n,&m)!=EOF) { build(1,n,1); stack<int> st; while(m--) { scanf("%s",op); int tmp; if(op[0]=='D') { scanf("%d",&tmp); st.push(tmp); update(tmp,0,1,n,1); } else if(op[0]=='Q') { scanf("%d",&tmp); printf("%d\n",query(tmp,1,n,1)); } else { tmp=st.top(); st.pop(); update(tmp,1,1,n,1); } } } return 0;}
stl做法:
对于要查询的点,用set找出其所在区间的上下界即可。
#include <cstdio>#include <set>#include <stack>using namespace std;int main(){ int n,m; scanf("%d%d",&n,&m); // getchar(); char ss[10]; set<int> s; stack<int> st; while(m--) { scanf("%s",ss); int t; if(ss[0]=='D') { scanf("%d",&t); s.insert(t); st.push(t); } else if(ss[0]=='Q') { scanf("%d",&t); int l=1,r=n; set<int>::iterator it; if(s.find(t)!=s.end()) puts("0"); else { it=s.upper_bound(t); if(it!=s.end()) { r=*(it)-1; } if(it!=s.begin()) { it--; l=*it+1; } printf("%d\n",r-l+1); } } else { int tmp=st.top(); st.pop(); s.erase(tmp); } } return 0;}
阅读全文
1 0
- poj2892,线段树单点更新,区间合并
- hdu5316 Magician (线段树+单点更新+区间查询+区间合并)
- hdu 3308 LCIS (线段树+单点更新+区间合并)
- hdu1540之线段树单点更新+区间合并
- hdu 3308 线段树单点更新 区间合并
- hdu.3308 LCIS(线段树,区间合并+单点更新)
- HDU 1540 Tunnel Warfare(线段树 区间合并 +单点更新)
- HDU 3308 LCIS(线段树区间合并 单点更新)
- hdu 1540(线段树单点更新 区间合并)
- HDU 3308 LCIS 线段树的单点更新,区间合并
- HDU 1540——Tunnel Warfare(线段树,区间合并+单点更新+单点查询)
- [HDU 5316] Magician (线段树+单点更新+区间询问+区间合并)
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并
- 线段树(单点更新+区间更新)
- cdoj 1061 秋实大哥与战争 线段树,合并区间,单点更新,单点查询区间长度
- 线段树区间更新+区间合并
- 线段树的区间更新区间合并
- zoj (单点更新区间查询:线段树)
- ios客户端:kCFErrorDomainCFNetwork Code=-1005
- oracle中常用函数大全
- 欢迎使用CSDN-markdown编辑器
- 每天五分钟linux(1)-ls
- 使用Promise封装简单Ajax方法
- poj2892,线段树单点更新,区间合并
- CSS页面布局技巧(三)
- iOS7 UIWebView设置支持加载HTTPS请求
- vue 中使用vue-echarts-v3编写chart柱状图,动态展示数据
- MySQL HA
- SVN 项目 无法运行第一步工作
- Thread.Sleep(0)的意义
- 动态生成验证码
- leetcode-122