Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 7367    Accepted Submission(s): 2870

Problem Description
During the War of Resistance Against Japan, tunnel warfare was carried out extensively in the vast areas of north China Plain. Generally speaking, villages connected by tunnels lay in a line. Except the two at the ends, every village was directly connected
with two neighboring ones.



Frequently the invaders launched attack on some of the villages and destroyed the parts of tunnels in them. The Eighth Route Army commanders requested the latest connection state of the tunnels and villages. If some villages are severely isolated, restoration
of connection must be done immediately!
 
Input
The first line of the input contains two positive integers n and m (n, m ≤ 50,000) indicating the number of villages and events. Each of the next m lines describes an event.



There are three different events described in different format shown below:



D x: The x-th village was destroyed.



Q x: The Army commands requested the number of villages that x-th village was directly or indirectly connected with including itself.



R: The village destroyed last was rebuilt.
 
Output
Output the answer to each of the Army commanders’ request in order on a separate line.
 
Sample Input
7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4
 
Sample Output
1
0
2
4
 
Source
 

【题解】

这题为求某个区间从最右往左(或从左往右)的连续序列提供了一个很好的思路。

具体的;

我们这道题的有没有被损坏可以构成一个01串。

然后我们用线段树的域来存储从最左端开始往右的连续的1的个数以及从最右端开始往左的连续的1的个数;

分别表示为llx[rt],rlx[rt];

在建树的时候可以维护一个序列全部为1的llx,rlx的信息;

然后单节点的操作也没问题,操作完修改就好了。

然后就是求一个位置x它所在的连续块的长度。

可以这样。

求1..x-1中从x-1往左连续的1的个数。

求x+1..n中从x+1往右连续的1的个数。

然后加上本身就好。

实现的方法很巧妙。自己看代码吧。

然后说一下。

这题hdu上是多组数据。

然后会重复出现某个村庄x。即x被多次损坏。

但只要修一次就能好。

但是如果你修好了x。栈中又出现了一次x。而你恰好要进行R操作。

那么你不能跳过这个x。虽然它已经修好了。但是还是要消耗一个R操作。

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#define lson begin,m,rt<<1
#define rson m+1,end,rt<<1|1 using namespace std; const int MAXN = 51000; int n, m;
int llx[MAXN * 4],rlx[MAXN*4],stack[MAXN*2],top;
bool lph[MAXN*4],rph[MAXN*4],huihuai[MAXN]; void push_up(int rt,int len) //合并区间要用到节点所代表的区间的长度。
{
llx[rt] = llx[rt << 1];
if (llx[rt] == (len - (len >> 1)))
llx[rt] += llx[rt << 1 | 1];
rlx[rt] = rlx[rt << 1 | 1];
if (rlx[rt] == (len >> 1))
rlx[rt] += rlx[rt << 1];
lph[rt] = lph[rt << 1];
rph[rt] = rph[rt << 1 | 1];
} void build(int begin, int end, int rt)
{
if (begin == end)
{
lph[rt] = rph[rt] = false;
llx[rt] = rlx[rt] = 1;
return;
}
int m = (begin + end) >> 1;
build(lson);
build(rson);
push_up(rt,end-begin+1);
} void up_data(int pos, int num,int begin, int end, int rt) //把某个点修好或毁坏
{
if (begin == end)
{
if (num == 1)
{
lph[rt] = rph[rt] = true;
llx[rt] = rlx[rt] = 0;
}
else
{
lph[rt] = rph[rt] = false;
llx[rt] = rlx[rt] = 1;
}
return;
}
int m = (begin + end) >> 1;
if (pos <= m)
up_data(pos, num, lson);
else
up_data(pos, num, rson);
push_up(rt, end - begin+1);
} int query_left(int l, int r, int begin, int end, int rt)//这是1..x-1中从x-1往左的连续的1的个数
{
if (l <= begin && end <= r)
return rlx[rt];
int m = (begin + end) >> 1;
if (r <= m)
return query_left(l, r, lson);
else
if (m < l)
return query_left(l, r, rson);
else
{
int temp1 = query_left(l, m, lson); //注意所求区间发生了改变。
int temp2 = query_left(m+1, r, rson);
if (r - m == temp2) //如果整个(m+1..r)都是连续的1则可以加上左半部分
return temp1 + temp2;
return temp2;
} } int query_right(int l, int r, int begin, int end, int rt)
{
if (l <= begin && end <= r)
return llx[rt];
int m = (begin + end) >> 1;
if (r <= m)
return query_right(l, r, lson);
else
if (m < l)
return query_right(l, r, rson);
else
{
int temp1 = query_right(l, m, lson);
int temp2 = query_right(m + 1, r, rson);
if (m - l + 1 == temp1)
return temp1 + temp2;
return temp1;
}
} void output_ans()
{
for (int i = 1; i <= m; i++)
{
char op[10];
int x;
scanf("%s", op);
if (op[0] == 'D')
{
scanf("%d", &x);
up_data(x, 1, 1, n, 1);
huihuai[x] = true;
top++;
stack[top] = x;
}
else
if (op[0] == 'R')
{
if (top > 0)
{
if (huihuai[stack[top]])
{
huihuai[stack[top]] = false;
up_data(stack[top], 0, 1, n, 1);
top--;
}
}
}
else
if (op[0] == 'Q')
{
scanf("%d", &x);
if (huihuai[x])
printf("0\n");
else
{
int sum1 = 0, sum2 = 0;
if (x >= 2)
sum1 = query_left(1, x - 1, 1, n, 1);
if (x <= n - 1)
sum2 = query_right(x + 1, n, 1, n, 1);
if (!huihuai[x])
sum2++;
printf("%d\n", sum1 + sum2);
}
}
}
} void init()
{
memset(huihuai, false, sizeof(huihuai));
memset(stack, 0, sizeof(stack));
top = 0;
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
//freopen("F:\\rush_out.txt", "w", stdout);
while (scanf("%d%d", &n, &m) != EOF)
{
init();
build(1, n, 1);
output_ans();
}
return 0; }

【38.96%】【hdu 1540】Tunnel Warfare的更多相关文章

  1. 【改革春风吹满地 HDU - 2036 】【计算几何-----利用叉积计算多边形的面积】

    利用叉积计算多边形的面积 我们都知道计算三角形的面积时可以用两个邻边对应向量积(叉积)的绝对值的一半表示,那么同样,对于多边形,我们可以以多边形上的一个点为源点,作过该点并且过多边形其他点中的某一个的 ...

  2. hdu 1540/POJ 2892 Tunnel Warfare 【线段树区间合并】

    Tunnel Warfare                                                             Time Limit: 4000/2000 MS ...

  3. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  4. 【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间 ...

  5. 【贪心】【模拟】HDU 5491 The Next (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5491 题目大意: 一个数D(0<=D<231),求比D大的第一个满足:二进制下1个个数在 ...

  6. 【动态规划】【二分】【最长上升子序列】HDU 5773 The All-purpose Zero

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5773 题目大意: T组数据,n个数(n<=100000),求最长上升子序列长度(0可以替代任何 ...

  7. 【动态规划】【KMP】HDU 5763 Another Meaning

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5763 题目大意: T组数据,给两个字符串s1,s2(len<=100000),s2可以被解读成 ...

  8. 【归并排序】【逆序数】HDU 5775 Bubble Sort

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 题目大意: 冒泡排序的规则如下,一开始给定1~n的一个排列,求每个数字在排序过程中出现的最远端 ...

  9. 【中国剩余定理】【容斥原理】【快速乘法】【数论】HDU 5768 Lucky7

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5768 题目大意: T组数据,求L~R中满足:1.是7的倍数,2.对n个素数有 %pi!=ai  的数 ...

随机推荐

  1. 【JZOJ4816】【NOIP2016提高A组五校联考4】label

    题目描述 输入 输出 样例输入 3 2 2 0 1 2 3 3 2 1 3 1 2 3 3 1 1 2 2 3 样例输出 4 2 12 数据范围 样例解释 解法 设f[i][j]为在第i个点填了j的合 ...

  2. 二.python数据结构的性能分析

    目录: 1.引言 2.列表 3.字典 一.引言 - 现在大家对 大O 算法和不同函数之间的差异有了了解.本节的目标是告诉你 Python 列表和字典操作的 大O 性能.然后我们将做一些基于时间的实验来 ...

  3. 大数据技术之Oozie

      第1章 Oozie简介 Oozie英文翻译为:驯象人.一个基于工作流引擎的开源框架,由Cloudera公司贡献给Apache,提供对Hadoop MapReduce.Pig Jobs的任务调度与协 ...

  4. bzoj1231 混乱的奶牛

    Description 混乱的奶牛 [Don Piele, 2007] Farmer John的N(4 <= N <= 16)头奶牛中的每一头都有一个唯一的编号S_i (1 <= S ...

  5. Android实战:手把手实现“捧腹网”APP(三)-----UI实现,逻辑实现

    Android实战:手把手实现"捧腹网"APP(一)-–捧腹网网页分析.数据获取 Android实战:手把手实现"捧腹网"APP(二)-–捧腹APP原型设计.实 ...

  6. hdu1907 尼姆博弈

    尼姆博弈的性质. 最后一个取输.若a1^a2^a3...^a4=0表示利他态T,不然为利己态S.充裕堆:1个堆里的个数大于2.T2表示充裕堆大于等于2,T1表示充裕堆大于等于1,T0表示无充裕堆.S2 ...

  7. [Java]ITOO初步了解 标签: javajbosstomcat 2016-05-29 21:14 3367人阅读 评论(34)

      开始接触Java的ITOO了,这两天在搭环境,结果发现,哇,好多没接触过的东西,先写篇博客来熟悉一下这些工具. JBoss 基于Tomcat内核,青胜于蓝   Tomcat 服务器是一个免费的开放 ...

  8. innerHTML属性的内存和性能问题

    使用innerHTML替换子节点可能会导致浏览器的内存占用问题,尤其是在IE中,问题更加明显.在删除带有时间处理程序或引用了其他js对象子树是,就有可能导致内存占用问题.假设某个元素有一个事件处理程序 ...

  9. shared_ptr的线程安全性

    一: All member functions (including copy constructor and copy assignment) can be called by multiple t ...

  10. importError: DLL load failed when import matplotlib.pyplot as plt

    importError: DLL load failed when import matplotlib.pyplot as plt 出现这种情况的原因, 大多是matplotlib的版本与python ...