L - Strange Mirroring (思维)
解释在后面
#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--; // 转为 0-basedlong long blk = k / s.size(); // 计算块编号long long pos = k % s.size(); // 计算块内位置// 检查 blk 的二进制中 1 的个数的奇偶性if(__builtin_popcountll(blk) % 2){ // 如果 1 的个数是奇数cout << flip(s[pos]); // 输出翻转后的字符}else{cout << s[pos]; // 否则直接输出原字符}}cout << "\n";return 0;
}
块编号的二进制 1
的个数决定是否翻转:
-
例如:
-
块
0
(二进制0
):1
的个数是0
(偶数),所以是S
本身。 -
块
1
(二进制1
):1
的个数是1
(奇数),所以是S
翻转。 -
块
2
(二进制10
):1
的个数是1
(奇数),所以是S
翻转。 -
块
3
(二进制11
):1
的个数是2
(偶数),所以是S
本身。 -
块
4
(二进制100
):1
的个数是1
(奇数),所以是S
翻转。
| -
__builtin_popcountll(blk)
:-
这是 GCC 的内置函数,用于计算一个
long long
类型整数的二进制表示中1
的个数。 -
也可以用
popcount
或手写函数实现。
-
-
找出规律就比较好写了,因为原题10e10的数据,暴力肯定会超时,就得找隐含的规律,但是发现变换顺序有些像倍增,2^n,所以主动联想二进制,然后就是了解对应的SQL函数