题意 :N个村子连成一条线,相邻的村子都有直接的地道进行相连,不相连的都由地道间接相连,三个命令,D x,表示x村庄被摧毁,R ,表示最后被摧毁的村庄已经重建了,Q x表示,与x直接或间接相连的村庄有多少个,当然包括他自己。
思路 :这是一道用线段树,树状数组,还有STL都可以做的题。。。。因为用线段树的更新什么的太麻烦,。。。。。所以我用了树状数组
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int maxn = 501252 ; int tree[maxn],data[maxn] ; bool vis[maxn] ; int n , m ; int lowbit(int x) { return (x & (-x)) ; } void add(int x,int value) { for(int i = x ; i <= n ; i += lowbit(i)) tree[i] += value ; } int get(int x) { int sum = 0 ; for(int i = x ; i ; i -= lowbit(i)) sum += tree[i] ; return sum ; } int binary_search(int v) { int l = 1 , r = n+1 ,i = n+2;//n+2是为了防止最后一个村庄找不到的时候没有返回值 while(l <= r) { int mid = (l + r) >> 1 ; if(get(mid) >= v) { r = mid-1 ; i = mid ; } else l = mid+1 ; } return i ; } int main() { while(~scanf("%d %d",&n,&m)) { int a , i = 0; while(m--) { getchar() ; char ch ; scanf("%c",&ch) ; if(ch == ‘D‘) { scanf("%d",&a) ; data[++i] = ++a ;//被摧毁的村庄都存在data数组里 vis[a] = true ; add(a,1) ; } else if(ch == ‘Q‘) { scanf("%d",&a) ; a ++ ; if(vis[a]) printf("0\n") ; else { int sum1,sum2 ; a = get(a) ; sum1 = binary_search(a) ; sum2 = binary_search(a+1) ; printf("%d\n",sum2-sum1-1) ; } } else if(ch == ‘R‘) { a = data[i--] ; vis[a] = false ; add(a,-1) ; } } } return 0; }
POJ 2892 Tunnel Warfare(树状数组+二分)
原文:http://www.cnblogs.com/luyingfeng/p/3565380.html