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.
输入的第一行包含两个正整数n和m(n,m≤50000),表示村庄和事件的数量。接下来的M行中的每一行描述一个事件。
有三种不同的事件以不同的格式描述,如下所示:
D x:第x村被摧毁了。
Q x:军区要求x村直接或间接联系的村庄数量,包括其自身。
R:上次被摧毁的村庄是重建的。
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
断断续续写了三天
坑点的话,一个村庄被摧毁多次,用栈保存的话,重建的时候要进行判断
杭电习惯坑,实际每次有多组数据,记得memset
询问就是找到你的村庄,然后左右查找能延伸多远
代码如下,已AC
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <cstring>
#include <queue>
#include <stack>
#include<cstdio>
#include<cmath>
using namespace std;
stack<int>A;
struct nod{
int l,r;//记录一个区间内,从左数和从右数最长连续
}node[200000];
void build(int l,int r,int p){
if(l==r){
node[p].l=1;
node[p].r=1;
return ;
}
int mid=(l+r)/2;
build(l,mid,p<<1);
build(mid+1,r,(p<<1)+1);
node[p].l=node[p].r=node[p<<1].r+node[(p<<1)+1].l;
}
void dest(int l,int r,int p,int c){
//printf("* ");
if(l==r&&l==c){
node[p].l=0;
node[p].r=0;
return ;
}
int mid=(l+r)/2;
if(mid>=c)
dest(l,mid,p<<1,c);
if(c>mid)
dest(mid+1,r,(p<<1)+1,c);
if(node[(p<<1)+1].l==r-mid)//这里卡了好久,后来发现了,之前错在去判断l和r是否相等
node[p].r=node[p<<1].r+node[(p<<1)+1].l;
else
node[p].r=node[(p<<1)+1].r;
if(node[p<<1].l==mid-l+1)
node[p].l=node[p<<1].l+node[(p<<1)+1].l;
else
node[p].l=node[p<<1].l;
}
void rebulit(int l,int r,int p,int c){//毁灭和重建可以合起来写,懒得改了
if(l==r&&l==c){
node[p].l=1;
node[p].r=1;
return ;
}
int mid=(l+r)/2;
if(mid>=c)
rebulit(l,mid,p<<1,c);
if(c>mid)
rebulit(mid+1,r,(p<<1)+1,c);
if(node[(p<<1)+1].l==r-mid)
node[p].r=node[p<<1].r+node[(p<<1)+1].l;
else
node[p].r=node[(p<<1)+1].r;
if(node[p<<1].l==mid-l+1)
node[p].l=node[p<<1].l+node[(p<<1)+1].l;
else
node[p].l=node[p<<1].l;
}
int ans=0;
int ll=0,rr=0;
void query(int l,int r,int p,int c){
int mid =(l+r)/2;
if(l==r){
if(node[p].l)
ll=rr=1;
else
ll=rr=0;
ans=node[p].l;
return ;
}
if(c<=mid){
query(l,mid,p<<1,c);
if(rr)
ans+=node[(p<<1)+1].l;
if(node[(p<<1)+1].l<r-mid) rr=0;
}
else{
query(mid+1,r,(p<<1)+1,c);
if(ll)
ans+=node[p<<1].r;
if(node[p<<1].r<mid-l+1) ll=0;
}
}
int main()
{
int n,m,w;
char c;
int haha[100000]={0};
while(~scanf("%d%d",&n,&m)){
ans=0;ll=0;rr=0;
for(int i=0;i<200000;i++){
node[i].l=node[i].r=0;
}
while(!A.empty()) A.pop();
build(1,n,1);
// for(int i=0;i<20;i++)
// printf("%d %d\n",node[i].l,node[i].r);
for(int i=0;i<m;i++){
getchar();
scanf("%c",&c);
if(c=='R'){
if(A.empty())
break;
while(!A.empty()){
int num=A.top();
A.pop();
if(haha[num]==1){
haha[num]=0;
rebulit(1,n,1,num);
break;
}
}
}
else{
scanf("%d",&w);
if(c=='D'){
haha[w]=1;
A.push(w);
// printf("=====");
dest(1,n,1,w);
}
if(c=='Q'){
query(1,n,1,w);
printf("%d\n",ans);
}
}
for(int i=0;i<20;i++)
printf("%d %d\n",node[i].l,node[i].r);
}
}
return 0;
}