AT_agc011_d [AGC011D] Half Reflector 題解

zifanwang發表於2024-11-13

\(1\) 表示 A\(0\) 表示 B,觀察進行一次操作後字串會發生什麼變化。首先當第一個數為 \(1\) 時,只會將第一個數變為 \(0\)。對於剩下的情況,手玩一下可以發現會將第一個數移到末尾,然後將所有數異或 \(1\)

先考慮暴力怎麼做,可以記一個指標 \(i\) 和當前應該給全體數異或的值 \(c\)。如果 \(a_i\neq c\),則將 \(a_i\) 改為 \(1\),否則將 \(i\) 往後移一位,\(c\) 取反。發現操作等價從左到右將每個數依次跟 \(i\bmod 2\) 比較,如果不同就改正,最多進行 \(2n\) 次操作後就會進入迴圈。當 \(n\) 為偶數時迴圈節長度為 \(1\),奇數長度為 \(2\),將 \(k\) 縮小後暴力操作即可,時間複雜度 \(\mathcal O(n)\)

參考程式碼:

#include<bits/stdc++.h>
#define mxn 200003
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define rept(i,a,b) for(int i=(a);i<(b);++i)
using namespace std;
int n,k,c,a[mxn];
char s[mxn];
signed main(){
	scanf("%d%d%s",&n,&k,s+1);
	rep(i,1,n)a[i]=s[i]=='A'?0:1;
	if(!(n&1))k=min(k,n*2);
	else if(k>=n*4)k=(k-n*2)%(n*2)+n*2;
	int r=1;
	rept(i,0,k){
		if(a[r]==c)a[r]^=1;
		else c^=1,r=r%n+1;
	}
	rept(i,0,n)putchar((a[r]^c)?'B':'A'),r=r%n+1;
	return 0;
}

相關文章