P5523 [yLOI2019] 珍珠 做题记录

别叹息太多告别,至少相遇很真切。

摇曳着盛放枯竭,时间从未停歇。

天涯浪迹的白雪,念念不忘山川蝴蝶。

听说有人孤负黑夜,偏要点亮人间的月。

简要题意

定义运算 anandbnot(aandb)and 指按位与,not 指按位取反。你需要动态维护一个数列,支持在前端插入,后端插入,询问一段前缀或后缀的 nand 和,保证在任意时刻数列中只有 01

思路

此处仅介绍前缀的做法,后缀与前缀维护方式相同。

的运算表:

容易发现,当参与运算的两个数字中只要有 那么运算结果必为 。所以当询问的前缀最后一个数字为 时,必然结果为 。而如果是 ,由于任意一段以 结尾的前缀的 和必为 。则只需计算在这个数字前面离这个数字最近的一个 到这个数字的 和。这是一段全 段。全 段的运算结果与 的个数奇偶性相关。考虑对于每个 维护 表示第 个位置距前面最近一个 的距离,初始时 表示前面没有

往后插入一个数的时候,当这个数为 时更新 。设插入的位置为 ,检查前面一个数,如果前面为 赋为 。否则按照 更新

往前插入一个数的时候,这个数为 时直接把 赋为 ,若为 ,则向后遍历每个值为 并且 的位置,更新这些位置的 值。每个数字最多被离其最近的前面的 更新一次,均摊时间复杂度

注意特判 在第一个数时的情况,没有进行 运算,值为

设有 次操作,时间复杂度为

Code

合理使用封装可以简化代码。此份代码省略题面提供的数据生成器。

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
75
#include<cstdio>
#include<iostream>
namespace lly
{
using namespace std;
constexpr int N=1e7+11;
struct deque
{
int a[N<<1],dis[N<<1],p1=N,p2=N;
inline void push_back(int x)
{
++x;
a[++p2]=x;
if(a[p2]==1)return;
if(a[p2-1]==2)dis[p2]=((dis[p2-1]==-1)?-1:(dis[p2-1]+1));
else dis[p2]=(p2==p1+1?-1:0);
}
inline void push_front(int x)
{
++x;
a[p1--]=x;
if(a[p1+1]==1) for(int i=p1+2;i<=p2&&a[i]==2;i++)dis[i]=i-p1-2;
else dis[p1+1]=-1;
}
inline int query(int x)
{
if(a[p1+x]==1) return x!=1;
if(dis[p1+x]==-1) return x&1;
if(dis[p1+x]==x-2) return (dis[p1+x]&1)^1;
return dis[p1+x]&1;
}
}o,r;
namespace collect
{
int s1=0,s2=0,s3=0,s4=0;
inline void put(int id,int x)
{
if(x)++s1;
if((id&1)&&!x)++s2;
if(!(id&1)&&x)++s3;
if(!(id&1023)&&!x)++s4;
}
inline void out(){cout<<s1<<" "<<s2<<" "<<s3<<" "<<s4<<"\n";}
}
inline void work()
{
int n;scanf("%d",&n);
Maker::Begin(n);
for(int i=1;i<=n;i++)
{
int x,y,z;Maker::Get_Nextline(x,y,z);
if(x==0)
{
if(y==0) o.push_front(z),r.push_back(z);
else o.push_back(z),r.push_front(z);
}
else
{
int ans;
if(y==0) ans=o.query(z);
else ans=r.query(z);
collect::put(i,ans);
}
}
collect::out();
}
}
int main()
{
#ifdef llydebug
freopen(".in","r",stdin);
#endif
lly::work();
return 0;
}
CPP

P5523 [yLOI2019] 珍珠 做题记录
https://www.llingy.top/posts/1261641707/
作者
llingy
发布于
2022年11月25日
许可协议