HDU 1540 Tunnel Warfare [二分 + 线段树]
2015-04-30 20:27
441 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1540
题意:
n个村庄排成一排,3种操作。
1,摧毁某个村庄
2,问与某个村庄x直接或间接连在一起的村庄有几个(包括它自己)
3,重建最后被摧毁的村庄
用1表示村庄村庄,0表示已被摧毁,维护好区间和。对于一个询问 x ,找到最大的 x2 满足 sum(x,x2)=x2−x+1 ,还有 最小的 x1 满足sum(x1,x)=x−x1+1 ,则与它相连的村庄个数为 x2−x1+1 个。可以用二分法去找。
从样例可以看出,3操作可以进行多步撤消,用一个栈将摧毁的过程记录下来就好。
另:对于单点更新区间求和,用树状数组更快。
题意:
n个村庄排成一排,3种操作。
1,摧毁某个村庄
2,问与某个村庄x直接或间接连在一起的村庄有几个(包括它自己)
3,重建最后被摧毁的村庄
用1表示村庄村庄,0表示已被摧毁,维护好区间和。对于一个询问 x ,找到最大的 x2 满足 sum(x,x2)=x2−x+1 ,还有 最小的 x1 满足sum(x1,x)=x−x1+1 ,则与它相连的村庄个数为 x2−x1+1 个。可以用二分法去找。
从样例可以看出,3操作可以进行多步撤消,用一个栈将摧毁的过程记录下来就好。
另:对于单点更新区间求和,用树状数组更快。
#include<iostream> #include<cmath> #include<stack> #include<cstring> #include<cstdio> using namespace std; #define debug(x) cout<<"debug "<<x<<endl; #define CHD int lc = node<<1, rc = node<<1|1; #define MID int mid = (L+R)>>1; const int maxn = 50001 << 2; int n,m; struct sgt{ int sum[maxn]; void init(int node,int L,int R){ if(L == R)sum[node] = 1; else{ MID;CHD; init(lc,L,mid); init(rc,mid+1,R); sum[node] = sum[lc]+sum[rc]; } } void update(int pos,int v,int node,int L,int R){ if(L == R){ sum[node] = v; } else { MID;CHD; if(pos <= mid) update(pos,v,lc,L,mid); else update(pos,v,rc,mid+1,R); sum[node] = sum[lc]+sum[rc]; } } int query(int from,int to,int node,int L,int R){ if(from <= L && R <= to){ return sum[node]; } MID;CHD; int ans = 0; if(from <= mid)ans += query(from,to,lc,L,mid); if(to > mid)ans += query(from,to,rc,mid+1,R); return ans; } int solve(int x){ if(query(x,x,1,1,n)==0)return 0; int ans = 0; int L = x,R = n+1; while(L < R){ MID; if(query(x,mid,1,1,n) == (mid-x+1))L = mid+1; else R = mid; } ans += L-x; L = 0,R = x; while(L < R){ MID; if(query(mid,x,1,1,n)==(x-mid+1))R = mid; else L = mid+1; } ans += x-R; //注意不要把x点记重复 return ans; } }tree; int main(){ while(scanf("%d%d",&n,&m) == 2){ tree.init(1,1,n); stack<int> s; int ls,q; char c; while(m--){ scanf(" %c",&c); switch(c){ case 'D': scanf("%d",&ls); s.push(ls); tree.update(ls,0,1,1,n); break; case 'R': if(!s.empty()){ tree.update(s.top(),1,1,1,n); s.pop(); } break; case 'Q': scanf("%d",&q); int ans = tree.solve(q); printf("%d\n",ans); break; } } } return 0; }
相关文章推荐
- HDU 1540 Tunnel Warfare [二分 + 线段树]
- POJ 2892 Tunnel Warfare || HDU 1540(树状数组+二分 || 线段树的单点更新+区间查询)
- hdu 1540 Tunnel Warfare (线段树维护左右最长连续区间)
- HDU 1540 Tunnel Warfare(用set解决线段树中单点查询)
- HDU 1540 Tunnel Warfare (线段树)
- hdu 1540 Tunnel Warfare 线段树--区间合并
- HDU1540 Tunnel Warfare (线段树区间合并)
- hdu 1540 Tunnel Warfare (区间线段树(模板))
- HDU - 1540 Tunnel Warfare 线段树 或者 让人心酸的暴力过
- HDU 1540 Tunnel Warfare(线段树)
- 【HDU - 1540】Tunnel Warfare 【线段树+单点更新+区间合并】
- hdu1540 poj2892 Tunnel Warfare 线段树端点更新 SBT
- hdu 1540 Tunnel Warfare 一个关于线段的故事~~~线段树是我无法言明的伤~
- hdu 1540 Tunnel Warfare(线段树区间统计)
- HDU - 1540Tunnel Warfare(线段树 单点更新 区间查询)
- hdu 1540 Tunnel Warfare(线段树单点更新+区间合并)
- hdu--1540 Tunnel Warfare(线段树+区间合并)
- HDU 1540 Tunnel Warfare(线段树区间合并)
- HDU 1540 Tunnel Warfare (线段树或set水过)
- hdu 1540 Tunnel Warfare 线段树 单点更新,查询区间长度,区间合并