题解:AT_abc477_d [ABC477D] Masking Tape

题意简述

  • N 个格子,初始颜色全是a。
  • 操作 1 X:格子 X胶带状态切换------ 有胶带就撕掉,没胶带就贴上。
  • 操作 2 C:所有当前没有胶带的格子,全部改成颜色c。有胶带的格子不受这次染色影响。

我们维护\(2\)个数组,lst[],用于时间戳 ,记录这个格子最近一次撕掉胶带是第几号查询;以及ok[],bool,表示当前 x 格子有没有贴胶带 。\(1\)表示贴了,\(0\)表示没贴。

再维护\(2\)个变量:g:保存最近一次 type2 的颜色。

核心思路

  1. 如果是 1 X(翻转胶带)

    • 情况 A:本来没有胶带 ,现在贴上胶带:

      贴上胶带之后,后面所有 type2 染色,都碰不到这个格子 。

      那贴上去这一刻,格子的颜色是什么?

      如果这个格子上次撕胶带的时间lst[x] ≤ 最近一次染色时间dq,说明在贴胶带前,它已经被全局染成g了。把这个颜色存到c[x]固定下来。ok[x]=1,标记贴上胶带。

    • 情况 B:本来贴着 ,现在撕掉:

      撕掉之后,这个格子会接收之后所有 type2 染色 。

      我们只要记下:这次撕胶带发生在第i号查询。lst[x]=i。ok[x]=0,标记被撕。

  2. 如果是 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;
    }