POJ 2892 Tunnel Warfare || HDU 1540(树状数组+二分 || 线段树的单点更新+区间查询)
题意 :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(树状数组+二分 || 线段树的单点更新+区间查询)的更多相关文章
- 树状数组+二分||线段树 HDOJ 5493 Queue
题目传送门 题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法 分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], ...
- BZOJ 3173 最长上升子序列(树状数组+二分+线段树)
给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? 由于序列是顺序插入的,所以当前插入的数字对之 ...
- POJ 1195 Mobile phones (二维树状数组或线段树)
偶然发现这题还没A掉............速速解决了............. 树状数组和线段树比较下,线段树是在是太冗余了,以后能用树状数组还是尽量用......... #include < ...
- 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 ...
- HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Tota ...
- st表、树状数组与线段树 笔记与思路整理
已更新(2/3):st表.树状数组 st表.树状数组与线段树是三种比较高级的数据结构,大多数操作时间复杂度为O(log n),用来处理一些RMQ问题或类似的数列区间处理问题. 一.ST表(Sparse ...
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ...
- [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】
题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...
- [BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】
题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log^2 n). 线段树比树状数组麻 ...
随机推荐
- Objective-C:runtime
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...
- Android_listView_exc
listView布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...
- Android_SeekBarAndProgressBar
xml文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...
- http://venkatbaggu.com/file-upload-in-asp-net-mvc-using-dropzone-js-and-html5/
http://venkatbaggu.com/file-upload-in-asp-net-mvc-using-dropzone-js-and-html5/ http://www.cnblogs.co ...
- java反射知识
java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称 ...
- 20160330javaweb之session 小练习
练习一:session 实现登录注销 package com.dzq.session.logout; import java.util.*; public class UserDao { /** * ...
- PHP mysql_real_escape_string() 函数防SQL注入
PHP MySQL 函数 定义和用法 mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符. 下列字符受影响: \x00 \n \r \ ' &quo ...
- Android应用不随手机屏幕旋转的方法
在主配置文件里面.在需要设置的activity项后面加上 android:screenOrientation="portrait",这个activity就保持竖屏显示了:在每个ac ...
- java_UML:继承/泛化、实现、依赖、关联、聚合、组合的联系与区别 (2016-07-12)
分别介绍这几种关系: UML关系:继承(泛化).实现.依赖.关联.聚合.组合的联系与区别 一.表示符号上的区别 二.具体区别与联系 1. 继承/泛化(Generalization) [泛化关系]:是一 ...
- RIME输入法
RIME输入法 1.可以输入汉语拼音. (1) RIME内置的「地球拼音」可以在选择完字之后按下「Shift+Enter」键,直接输入汉语拼音,并且是带声调的. (2) 自己配置汉语拼音方案. 2.五 ...