D - Strange Mirroring Editorial by en_translator
Let us call
- the \(1\)-st through \(|S|\)-th characters block \(0\),
- the \((|S|+1)\)-th through \((2 \times |S|)\)-th characters block \(1\),
- the \((2 \times |S| + 1)\)-th through \((3 \times |S|)\)-th characters block \(1\),
- \(\dots\)
and so on. Then, in the resulting sequence,
- Block \(0\) is \(S\).
- Block \(1\) is \(S\) with (upper- and lower-) case flipped.
- Block \(2\) is \(S\) with (upper- and lower-) case flipped.
- Block \(3\) is \(S\).
- Block \(4\) is \(S\) with (upper- and lower-) case flipped.
- Block \(5\) is \(S\).
- Block \(6\) is \(S\).
- Block \(7\) is \(S\) with (upper- and lower-) case flipped.
- \(\dots\)
Starting from one block solely forming \(S\), the operation repeatedly append the string itself after flipping the case. After repeating it \(k\) times, there will be \(2^k\) blocks.
Therefore, we have the following fact:
- Suppose that we want to determine a character in the \(B\)-th block. In the binary representation of \(B\), if the most significant digit \(1\) is at the \(2^k\)s place, then block \(B\) equals block \((B-2^k)\) with the case flipped.
We can follow this step until we reach \(B=0\) to get the correct answer, but we can also come to the following conclusion:
- If the number of digits \(1\) in the binary representation of \(B\) is even, then block \(B\) is \(S\) itself.
- If the number of digits \(1\) in the binary representation of \(B\) is odd, then block \(B\) is \(S\) with case flipped.
Hence, the problem can be answered by determining which block the \(K_i\)-th character belongs to and the position of that character in the block, and finding how many digits \(1\) are there in the binary representation of the block number.
One can count the digits \(1\) in the binary representation using a loop, or a function like popcount that finds the number of standing bits in a binary representation.
Sample code (C++):
#include<bits/stdc++.h>
using namespace std;
char flip(char c){
if('a'<=c && c<='z'){
return (c-'a')+'A';
}
else{
return (c-'A')+'a';
}
}
int main(){
string s;
cin >> s;
int q;
cin >> q;
for(int i=0;i<q;i++){
if(i){cout << " ";}
long long k;
cin >> k;
k--;
long long blk=k/s.size();
long long pt=k%s.size();
if(popcount((unsigned long long)blk)%2){
// if(__builtin_popcountll(blk)%2){
// if(__builtin_parityll(blk)){
cout << flip(s[pt]);
}
else{
cout << s[pt];
}
}cout << "\n";
return 0;
}
posted:
last update: