点我看题目

题意 :N个村子连成一条线,相邻的村子都有直接的地道进行相连,不相连的都由地道间接相连,三个命令,D x,表示x村庄被摧毁,R  ,表示最后被摧毁的村庄已经重建了,Q x表示,与x直接或间接相连的村庄有多少个,当然包括他自己。

思路 :这是一道用线段树,树状数组,还有STL都可以做的题。。。。因为用线段树的更新什么的太麻烦,。。。。。所以我用了树状数组

#include <iostream>
#include <stdio.h>
#include <string.h> using namespace std; const int maxn = ;
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 = ;
for(int i = x ; i ; i -= lowbit(i))
sum += tree[i] ;
return sum ;
} int binary_search(int v)
{
int l = , r = n+ ,i = n+;//n+2是为了防止最后一个村庄找不到的时候没有返回值
while(l <= r)
{
int mid = (l + r) >> ;
if(get(mid) >= v)
{
r = mid- ;
i = mid ;
}
else l = mid+ ;
}
return i ;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
int a , i = ;
while(m--)
{
getchar() ;
char ch ;
scanf("%c",&ch) ;
if(ch == 'D')
{
scanf("%d",&a) ;
data[++i] = ++a ;//被摧毁的村庄都存在data数组里
vis[a] = true ;
add(a,) ;
}
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+) ;
printf("%d\n",sum2-sum1-) ;
}
}
else if(ch == 'R')
{
a = data[i--] ;
vis[a] = false ;
add(a,-) ;
}
}
}
return ;
}

以前用树状数组做的,现在用线段树做的,因为没有初始化WA到死,杭电上是多组数据,所以一开始也WA了,因为每次重建的时候建的是最后一个村子,将被摧毁的村子放入栈中就可以了,然后要标记一下,所有的村子存在即为0,摧毁了即为1,更新用单点,查询用区间,查询x村子时,寻找左边离他最近的那个被摧毁的村庄即1,以及最右边那个被摧毁的村庄,然后两个相减加1即为结果,但是如果他本身就被摧毁了直接是0。

 //
#include <cstdio>
#include <cstring>
#include <iostream> using namespace std ; int lz[*],p[ * ],vis[ * ],stk[*] ; void pushup(int rt)
{
p[rt] = p[rt << ] + p[rt << | ] ;
}
void update(int x,int l,int r,int rt,int sc)
{
if(l == r)
{
p[rt] = sc ;
return ;
}
int mid = (l+r) >> ;
if(x <= mid)
update(x,l,mid,rt << , sc) ;
else
update(x,mid+,r,rt << | , sc) ;
pushup(rt) ;
}
int query(int L,int R,int l,int r,int rt)
{
int sum = ;
if(L <= l && r <= R)
{
return p[rt] ;
}
int mid = (l+r) >> ;
if(mid >= L)
sum += query(L,R,l,mid,rt << ) ;
if(mid < R)
sum += query(L,R,mid+,r,rt << | ) ;
return sum ;
}
int findd(int l,int r,int x,int rt)
{
if(l == r)
{
return l;
}
int mid = (l+r) >> ;
if(x <= p[rt << ])
return findd(l,mid,x,rt << ) ;
else return findd(mid+,r,x-p[rt << ],rt << | ) ;
}
int main()
{
int n, m,x;
char ch[] ;
while(~scanf("%d %d",&n,&m))
{
int top = ;
memset(p,,sizeof(p)) ;
memset(vis,,sizeof(vis)) ;
for(int i = ; i < m ; i++)
{
scanf("%s",ch) ;
if(ch[] == 'R')
{
if(top != )
{
vis[stk[top-]] = ;//村庄存在即为0,被摧毁即为1
update(stk[top-],,n,,) ;
top-- ;
}
}
else if(ch[] == 'D')
{
scanf("%d",&x) ;
vis[x] = ;
stk[top++] = x ;
update(x,,n,,) ;
}
else if(ch[] == 'Q')
{
scanf("%d",&x) ;
if(vis[x])
{
printf("0\n") ;
continue ;
}
int l,r ;
int l1 = query(,x,,n,) ;//x村庄左边的和
if(l1 == )//如果和为0,说明x村庄左边全部都存在
l = ;
else l = findd(,n,l1,)+;//找出左边离x最近的那个一,既不存在的那个村庄
int r1 = query(x,n,,n,) ;
if(r1 == )
r = n;
else r = findd(,n,l1+,)- ;
printf("%d\n",r-l+) ;
}
}
}
return ;
}

POJ 2892 Tunnel Warfare || HDU 1540(树状数组+二分 || 线段树的单点更新+区间查询)的更多相关文章

  1. 树状数组+二分||线段树 HDOJ 5493 Queue

    题目传送门 题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法 分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], ...

  2. BZOJ 3173 最长上升子序列(树状数组+二分+线段树)

    给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? 由于序列是顺序插入的,所以当前插入的数字对之 ...

  3. POJ 1195 Mobile phones (二维树状数组或线段树)

    偶然发现这题还没A掉............速速解决了............. 树状数组和线段树比较下,线段树是在是太冗余了,以后能用树状数组还是尽量用......... #include < ...

  4. HDU 5618 Jam's problem again(三维偏序,CDQ分治,树状数组,线段树)

    Jam's problem again Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  5. HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)

    Weak Pair Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Tota ...

  6. st表、树状数组与线段树 笔记与思路整理

    已更新(2/3):st表.树状数组 st表.树状数组与线段树是三种比较高级的数据结构,大多数操作时间复杂度为O(log n),用来处理一些RMQ问题或类似的数列区间处理问题. 一.ST表(Sparse ...

  7. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  8. [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

    题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...

  9. [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

    题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...

随机推荐

  1. 简明网络I/O模型---同步异步阻塞非阻塞之惑

    转自:http://www.jianshu.com/p/55eb83d60ab1 网络I/O模型 人多了,就会有问题.web刚出现的时候,光顾的人很少.近年来网络应用规模逐渐扩大,应用的架构也需要随之 ...

  2. 实现一个脚本语言Raven(一)

    之前实现了Raven语言的0.1版,仅仅支持表达式处理与控制语句,由于不支持数组.函数.类,甚至都不是图灵完全的语言. 现在参考vczh的博客打算重新写一遍Raven语言.陈祖不愧是神啊,高中就写出支 ...

  3. Apache 配置多端口 多虚拟主机 局域网访问

    \wamp\bin\apache\Apache2.4.4\conf\extra\httpd-vhosts.conf 修改如下 NameVirtualHost *:80          Documen ...

  4. html-01

    1.HTML:超文本标记语言,由浏览器解析成页面.html文件是以.html或者 .htm 2.HTML的作用   |- 控制页面的外观.   |- 发布帮助文档 3.常见的浏览器    |-IE:微 ...

  5. Asp.Net静态资源动态压缩之WebOptimization

    一.Asp.Net中对Css/Js的动态压缩工具 WebOptimization 在Asp.NetMVC自带的模板项目中自动引入了当前WebOptimization工具.如果使用的空模板Nuget命令 ...

  6. 找不到可安装的ISAM

    转载:http://www.cnblogs.com/zyc2/archive/2005/06/28/182492.html   读取excel数据 到 datagrid 出现:找不到可安装的ISAM  ...

  7. C#微信公众号开发 -- (七)自定义菜单事件之VIEW及网页(OAuth2.0)授权

    通俗来讲VIEW其实就是我们在C#中常用的a标签,可以直接在自定义菜单URL的属性里面写上需要跳转的链接,也即为单纯的跳转. 但更多的情况下,我们是想通过VIEW来进入指定的页面并进行操作. 举一个简 ...

  8. ACM——2的n次方

    2的N次方 时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte 总提交:1715            测试通过:838 描述 编程精确计算2 ...

  9. 利用putty实现文件在linux上传和下载

    利用putty实现文件上传和下载:1.打开windows命令提示符窗口d:(putty在d盘下)cd putty(pscp.exe所在目录)2:上传(主要利用pscp程序)pscp d:/jdk-8u ...

  10. Codevs 1171 潜伏者 2009年NOIP全国联赛提高组

    1171 潜伏者 2009年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description [问题描述] R 国和S 国正陷 ...