用 \(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;
}