2023 Hubei Provincial Collegiate Programming Contest TF

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 3e6 + 9;

int a[N];

char b[N];

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;cin >> n;
    for(int i = 0;i <= 2 * n + 1; ++ i)cin >> a[i];

    char ch = 'a';

    b[0] = '&';
    b[1] = '|';
    for(int i = 2, r = 1; i < 2 * n + 2; i++)
    {
      while(r < i + a[i] - 1)
      {
        r++;
        b[r] = b[2*i - r];
      }
      if(i&1) b[i] = '|';
      if(b[i] == 0)
        b[i] = ch, ch = (ch == 'a')?'b':'a';
    }
    for(int i = 2;i <= 2 * n + 1;i += 2)cout << b[i];
    return 0;
}

主要解释为什么要交替填a、b:

首先,我们要明确两个性质:

①任何是字母的位置,a[i]>=2

②如果一个|的位置,a[i]=1,那么就说明发生了a和b的交替

对于样例abaaa->&|a|b|a|a|a|

刚开始的时候,i=2,r=1,a[i]必然大于等于2,这时候r会连续填两个数字,这时候因为b[3]还是空的,b[2]就也会复制一个空的,并且r会落在3;

接下来,因为a[3]=1,r就不会移动,然后i又超过了r……

总结规律,我们发现,如果a[i]>1,那么r就会连续移动,超过i的位置;一旦移动到a[i]=1的位置,那么r就会停止移动,等i移过来

i每次只能向前移动1个位置,而也只有a[i]=1的时候,r才不会移动

所以只有a[i]=1的位置,i才可以超过r

也就是只有a和b发生交替的时候,i才可以超过r,而i一旦超过了r,下次填字符的时候就会出现填入一个空字符的情况,因为这个空字符是由于原串中a和b交替导致的,所以这时候就要进行一次ch的变换。

而如果a[i]的值都比较大,那么r就比较大,2*i-r就比较小,每次填入的时候就会用已经填入的字符来填当前的新字符,就不会出现留空的情况,也就不会出现a和b的交替了。

posted @ 2024-03-25 14:22  Gold_stein  阅读(16)  评论(0编辑  收藏  举报