题意简述
- N 个格子,初始颜色全是
a。 - 操作 1 X:格子 X胶带状态切换------ 有胶带就撕掉,没胶带就贴上。
- 操作 2 C:所有当前没有胶带的格子,全部改成颜色
c。有胶带的格子不受这次染色影响。
我们维护\(2\)个数组,lst[],用于时间戳 ,记录这个格子最近一次撕掉胶带是第几号查询;以及ok[],bool,表示当前 x 格子有没有贴胶带 。\(1\)表示贴了,\(0\)表示没贴。
再维护\(2\)个变量:g:保存最近一次 type2 的颜色。
核心思路
-
如果是
1 X(翻转胶带)-
情况 A:本来没有胶带 ,现在贴上胶带:
贴上胶带之后,后面所有 type2 染色,都碰不到这个格子 。
那贴上去这一刻,格子的颜色是什么?
如果这个格子上次撕胶带的时间
lst[x]≤ 最近一次染色时间dq,说明在贴胶带前,它已经被全局染成g了。把这个颜色存到c[x]固定下来。ok[x]=1,标记贴上胶带。 -
情况 B:本来贴着 ,现在撕掉:
撕掉之后,这个格子会接收之后所有 type2 染色 。
我们只要记下:这次撕胶带发生在第
i号查询。lst[x]=i。ok[x]=0,标记被撕。
-
-
如果是
2 C(全局染色,无胶带格子改成 C)
不用循环,直接更新全局变量:g=C,dq=i(把这次染色的查询号记下来)。
最后输出答案的时候:
对每个格子 i:
-
如果
ok[i]=true:现在还贴着胶带 。胶带挡住后面所有染色,它的颜色就是当初贴胶带那一刻存下来的c[i]。 -
如果
ok[i]=false:现在没有胶带,那要看【撕掉胶带的时间】和【最后一次全局染色时间】谁更晚就行了。#include<bits/stdc++.h>
#define fr1(i,a,b) for(int (i)=(a);(i)<=(b);++(i))
#define fr2(i,a,b) for(int (i)=(a);(i)>=(b);--(i))
#define fr3(i,a,b,n) for(int (i)=(a);(i)<=(b);(i)+=(n))
#define fr4(i,a,b,n) for(int (i)=(a);(i)>=(b);(i)-=(n))
#define fv(i,p) for(auto (i):(p))
#define written using
#define ll long long
#define ull unsigned ll
#define pii pair<int,int>
#define pll pair<ll,ll>
#define by namespace
#define _1st first
#define _2nd second
#define qz5zwangzihan1 std
#define y1 yy1
#define elif else if
#define RT return
#define debug cout<<endl<<"-------------------------------------------------------------"<<endl
written by qz5zwangzihan1;
const int MAXN=300005;
int n,q;
bool ok[MAXN];
char c[MAXN];
int lst[MAXN];
char g;
int dq;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
cin>>n>>q;
g='a';
fr1(i,1,n) lst[i]=0;
fr1(i,1,q){
int op;
cin>>op;
if(op==1){
int x;cin>>x;
if(!ok[x]){
ok[x]=1;
if(lst[x]<=dq){
c[x]=g;
}
}else{
ok[x]=0;
lst[x]=i;
}
}else{
char ccc;
cin>>ccc;
g=ccc;
dq=i;
}
}
string ans;
fr1(i,1,n){
if(ok[i]){
ans+=c[i];
}else{
if(lst[i]<=dq){
ans+=g;
}else{
ans+=c[i];
}
}
}
cout<<ans;
RT 0;
}