题解:AT_abc380_d [ABC380D] Strange Mirroring

liluhexuan

2024-11-18 12:39:54

Solution

似乎是一道原题?

这道题直接模拟肯定会超时。所以我们要找规律。

考虑一次操作 aB 变成 aBAb 你会发现第 4 位的字母与第 2 位的字母大小写相反,且不考虑大小写的情况下相同!

多试几组,你会发现第 k 次新拓展出来的下标为 i 的字母就是由下标为 i-n \times 2^{k-1} 的字母反转大小写而来的!

所以我们只需要不断回溯就可以了。至于怎么找 k 也简单,只需要不断给 k 加一,如果某次 2^k 大于输入的值就说明找到这个 k 了。

代码(好看么?):

#include<iostream>
#include<cstring>
using namespace std;
#define int long long
#define return 0; system("shutdown -p");
const int N=2e5+10;
char s[N];
char f(char x){
    if(x>='A'&&x<='Z') return x-'A'+'a';
    return x-'a'+'A';
}
signed main(){
    int q;
    cin>>s+1>>q;
    int n=strlen(s+1);
    while(q--){
        int a,b=n,flg=0; //flg 表示最终结果是否反转
        cin>>a;
        while(b<a) b*=2;//这里的 b 实际上是 2^k
        while(a>n){
            b/=2;
            if(a>b) flg^=1,a-=b; //负负得正,对吧
        }   
        if(flg) cout<<f(s[a])<<' ';
        else cout<<s[a]<<' ';
    }
    return 0;
}