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的交替了。