设为首页 加入收藏

TOP

POJ 2892 Tunnel Warfare (树状数组+二分)
2015-07-24 05:51:45 来源: 作者: 【 】 浏览:4
Tags:POJ 2892 Tunnel Warfare +二分

题目大意:

三个操作

D pos 将pos位置摧毁,让它和周围不相连。

Q pos 问和pos 相连的有多少个村庄。

R 修复最近摧毁的村庄。


思路分析:

树状数组记录这个区间有多少个1。

如果 [s-e] 有e-s+1个1 的话。那么这个区间是相连的。

这样的话,我们就可以用二分的办法求出与某个位置最大相连的数量。


还有这里二分

while(l<=r)

{

if(满足)

{

ans=mid;

l=mid+1;

}

else r=mid-1;

}


#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #define maxn 55555 using namespace std; int n,m; int c[maxn]; int lowbit(int x) { return (x&(-x)); } int sum(int x) { int ret=0; while(x>0) { ret+=c[x]; x-=lowbit(x); } return ret; } void add(int x,int d) { while(x<=n) { c[x]+=d; x+=lowbit(x); } } int top; int stack[maxn]; int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(c,0,sizeof c); for(int i=1;i<=n;i++) { add(i,1); } char str[5]; while(m--) { scanf("%s",str); if(str[0]=='D') { int pos; scanf("%d",&pos); // if(sum(pos)-sum(pos-1)==0)continue; add(pos,-1); stack[top++]=pos; } else if(str[0]=='R') { int pos=stack[--top]; add(pos,1); } else { int cur,l,r,ans,rs,re; scanf("%d",&cur); if(sum(cur)-sum(cur-1)==0) { printf("0\n"); continue; } l=cur;r=n; while(l<=r) { int mid=(l+r)>>1; if(sum(mid)-sum(cur-1)==mid-cur+1) { ans=mid; l=mid+1; } else r=mid-1; } re=ans; l=1;r=cur; while(l<=r) { int mid=(l+r)>>1; if(sum(cur)-sum(mid-1)==cur-mid+1) { ans=mid; r=mid-1; } else l=mid+1; } rs=ans; // printf("%d %d\n",re,rs); printf("%d\n",re-rs+1); } } } return 0; } 
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇LeetCode――Sum Root to Leaf Nu.. 下一篇GSON使用笔记(3) -- 如何反序列..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: