2022江苏省赛 K. aaaaaaaaaaA heH heH nuN (构造题)

题意: nunhehheh为前缀, x个a为后缀(x >= 1)的字符串称为目标串,构造出只含小写字母的字符串使得恰好含k个子序列为目标串
思路: 答案串的前缀固定为nunhehhe,对于后面的一个h,若这个h后面有x个a,则以这个h做最后一个h的贡献为 \(2^x\)-1。 容易想到利用k的二进位来构造:

  • 若k的第pos位为1,则一个h后面需要有pos个a。
  • 这样得到的串的贡献是 k - cnt (cnt为k的二进制位为1的个数)
  • 这个cnt只需在最后一个a前面多加cnt个h就凑上了。
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
#define PII pair<int, char>
//#define int long long
const int N = 1e6 + 5;
const int M = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double PI = acos(-1.0);

void solve() {
int n; cin >> n;
if( n == 0 ) {
 cout << "apex" << '\n'; return;
} 
if( n == 1 ) {
 cout << "nunhehheha" << '\n'; return;
} 
string ss = "";
vector<int> ve;
int cnt = 0;
for ( int i = 1; i <= 30; ++ i) { //为了方便,从1位开始
 if( n & (1 << i) ) ve.push_back(i - 1), ++ cnt;
}
if( n & 1 ) ++ cnt;
int pre = 0; bool f = 1;
for ( auto i : ve ) {
 for ( int j = 1; j <= i - pre; ++ j ) {
   ss += "a";      
 }
 ss +="h";
 pre = i;
} 
reverse(ss.begin(), ss.end());
for ( int j = 1; j <= cnt; ++ j ) ss += "h"; ss += "a";
cout << "nunhehhe" + ss << '\n';
}
int main () {
IOS
int t; cin >> t;
while( t -- ) solve();

return 0;
}

image

posted @ 2022-07-05 20:30  qingyanng  阅读(192)  评论(0编辑  收藏  举报