洛谷 P1503 鬼子进村

题目背景

小卡正在新家的客厅中看电视。电视里正在播放放了千八百次依旧重播的《亮剑》,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战。

题目描述

描述 县城里有n个用地道相连的房子,第i个只与第i-1和第i+1个相连。这是有m个消息依次传来

1、消息为D x:鬼子将x号房子摧毁了,地道被堵上。

2、消息为R :村民们将鬼子上一个摧毁的房子修复了。

3、消息为Q x:有一名士兵被围堵在x号房子中。

李云龙收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。

输入输出格式

输入格式:

第一行2个整数n,m(n,m<=50000)。

接下来m行,有如题目所说的三种信息共m条。

输出格式:

对于每一个被围堵的士兵,输出该士兵能够到达的房子数。

输入输出样例

输入样例#1:

7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4

输出样例#1: ·

1
0
2
4

说明

若士兵被围堵在摧毁了的房子中,那只能等死了。。。。。。

思路:对于第一种操作,我们可以开一个vis数组记录某个地洞是否被堵了,同时要把堵了的地洞加入一个栈,为后面的第二种操作做准备,第二种操作,直接就把栈顶元素弹出来就好了,再把相应的vis数组清空,但是,第三种操作,貌似有些棘手,但是,我们仔细想一下,被困队员能到达的地洞可以认为是一个线性的数列,也就是说,是有左右边界的,而左右边界又正好是这个被困队员所在的被堵洞口的前驱和后继!用splay来维护一下就可以解决了!

代码:

#include<cstdio>
#include<cctype>
#include<stack>
#define maxn 50007
using namespace std;
int n,m,root,tot;
char c[2];
inline int qread() {
  char c=getchar();int num=0,f=1;
  for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
  for(;isdigit(c);c=getchar()) num=num*10+c-'0';
  return num*f;
}
bool vis[maxn];
struct Tree {
  int fa,ch[2],val;
}t[maxn];
inline void rotate(int x) {
  int y=t[x].fa,z=t[y].fa;
  int k=t[y].ch[1]==x;
  t[z].ch[t[z].ch[1]==y]=x;
  t[x].fa=z;
  t[y].ch[k]=t[x].ch[k^1];
  t[t[x].ch[k^1]].fa=y;
  t[x].ch[k^1]=y,t[y].fa=x;
}
inline void splay(int x, int rt) {
  while(t[x].fa!=rt) {
  	int y=t[x].fa,z=t[y].fa;
  	if(z!=rt) (t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
  	rotate(x);
  }
  if(!rt) root=x;
}
inline void insert(int x) {
  int u=root,f=0;
  while(u&&t[u].val!=x) {
  	f=u;
  	u=t[u].ch[x>t[u].val];
  }
  if(u);
  else {
  	u=++tot;
  	if(f) t[f].ch[x>t[f].val]=u;
  	t[u].fa=f,t[u].val=x;
  }
  splay(u,0);
}
inline void find(int x) {
  int u=root;
  if(!u) return;
  while(t[u].ch[x>t[u].val]&&x!=t[u].val) u=t[u].ch[x>t[u].val];
  splay(u,0);
}
inline int nxt(int x, int f) {
  find(x);
  int u=root;
  if(t[u].val>x&&f) return u;
  if(t[u].val<x&&!f) return u;
  u=t[u].ch[f];
  while(t[u].ch[f^1]) u=t[u].ch[f^1];
  return u;
}
inline void sc(int x) {
  int last=nxt(x,0),next=nxt(x,1);
  splay(last,0),splay(next,last);
  t[next].ch[0]=0;
}
stack<int>q;
int main() {
  n=qread(),m=qread();
  insert(0),insert(n+1);
  for(int i=1,x;i<=m;++i) {
  	scanf("%s",c);
  	if(c[0]=='D') {
  	  x=qread(),vis[x]=1;
	  q.push(x),insert(x);	
	}
	if(c[0]=='R') {
	  vis[q.top()]=0;
	  sc(q.top());
	  q.pop();
	}
	if(c[0]=='Q') {
	  x=qread();
	  if(vis[x]) printf("0
");
	  else printf("%d
",t[nxt(x,1)].val-t[nxt(x,0)].val-1);
	}
  }
  return 0;
}
原文地址:https://www.cnblogs.com/grcyh/p/10569465.html