洛谷 1503 鬼子进村 题解

题意简述

给定一个长度为序列,一开始都是。支持三种操作:

  1. 修改某一个位置为
  2. 撤销上一次修改
  3. 询问包含某个位置的最长的连续的的个数。

思路

维护位置,二分得到左右,相减即珂。

实现注意点

  1. 左右边界。左是 ,右是
  2. 关于撤销的操作:用一个栈维护删除的位置,每一次撤销就是取栈顶。(我是用实现的栈,因为我不是很会用,不要在意)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
multiset<int> S;
multiset<int>::iterator it;
vector<int> D;
void Erase1(int x)
{
it=S.find(x);
S.erase(it);
}

int n,m;
void R1(int &x)
{
x=0;char c=getchar();int f=1;
while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=(f==1)?x:-x;
}
void Input_Soviet()
{
R1(n),R1(m);
S.insert(0);
S.insert(n+1);
F(i,1,m)
{
char o[4];scanf("%s",o);
if (o[0]=='D')
{
int x;R1(x);
S.insert(x);
D.push_back(x);
}
if (o[0]=='R')
{
int last=*(D.end()-1);
if (S.find(last)!=S.end())
{
Erase1(last);
D.pop_back();
}
}
if (o[0]=='Q')
{
int x;R1(x);
it=S.upper_bound(x);it--;
int ll=*it;
int rr=*(S.lower_bound(x));
printf("%d\n",max(rr-ll-1,0));
}
}
}

#define Flan void
Flan IsMyWife()
{
Input_Soviet();
}
}
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}
w