For the given integer n (n>2) let’s write down all the strings of length n which contain n−2 letters ‘a’ and two letters ‘b’ in lexicographical (alphabetical) order.
Recall that the string s of length n is lexicographically less than string t of length n, if there exists such i (1≤i≤n), that si<ti, and for any j (1≤j<i) sj=tj. The lexicographic comparison of strings is implemented by the operator < in modern programming languages.
For example, if n=5 the strings are (the order does matter):
aaabb
aabab
aabba
abaab
ababa
abbaa
baaab
baaba
babaa
bbaaa
It is easy to show that such a list of strings will contain exactly n⋅(n−1)2 strings.
You are given n (n>2) and k (1≤k≤n⋅(n−1)2). Print the k-th string from the list.
Input
The input contains one or more test cases.
The first line contains one integer t (1≤t≤104) — the number of test cases in the test. Then t test cases follow.
Each test case is written on the the separate line containing two integers n and k (3≤n≤105,1≤k≤min(2⋅109,n⋅(n−1)2).
The sum of values n over all test cases in the test doesn’t exceed 105.
Output
For each test case print the k-th string from the list of all described above strings of length n. Strings in the list are sorted lexicographically (alphabetically).
Example
Input
7
5 1
5 2
5 8
5 10
3 1
3 2
20 100
Output
aaabb
aabab
baaba
bbaaa
abb
bab
aaaaabaaaaabaaaaaaaa
思路:考虑两个b的位置,左边的b右边有几个位置,对于这个b来说,就有几种情况,二分去找这个区间,然后再判断第二个b的位置就可以了。
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;ll k;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%lld",&n,&k);
ll l=1,r=n-1,mid;
while(l<=r)
{
int mid=l+r>>1;
if((1ll+mid)*mid/2<=k) l=mid+1;
else r=mid-1;
}
ll pos1,pos2;
if((r+1)*r/2==k)
{
pos1=n-r;
pos2=pos1+1;
}
else
{
pos1=n-l;
pos2=n-(k-(r+1)*r/2-1);
}
for(int i=1;i<=n;i++)
{
if(i==pos1||i==pos2) cout<<'b';
else cout<<'a';
}
cout<<endl;
}
return 0;
}
努力加油a啊,(o)/~