Dense Subsequence

时间:2021-09-02 05:53:49
Dense Subsequence
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a string s, consisting of lowercase English letters, and the integer m.

One should choose some symbols from the given string so that any contiguous subsegment of length m has at least one selected symbol. Note that here we choose positions of symbols, not the symbols themselves.

Then one uses the chosen symbols to form a new string. All symbols from the chosen position should be used, but we are allowed to rearrange them in any order.

Formally, we choose a subsequence of indices 1 ≤ i1 < i2 < ... < it ≤ |s|. The selected sequence must meet the following condition: for every j such that 1 ≤ j ≤ |s| - m + 1, there must be at least one selected index that belongs to the segment [j,  j + m - 1], i.e. there should exist a k from 1 to t, such that j ≤ ik ≤ j + m - 1.

Then we take any permutation p of the selected indices and form a new string sip1sip2... sipt.

Find the lexicographically smallest string, that can be obtained using this procedure.

Input

The first line of the input contains a single integer m (1 ≤ m ≤ 100 000).

The second line contains the string s consisting of lowercase English letters. It is guaranteed that this string is non-empty and its length doesn't exceed 100 000. It is also guaranteed that the number m doesn't exceed the length of the string s.

Output

Print the single line containing the lexicographically smallest string, that can be obtained using the procedure described above.

Examples
input
3
cbabc
output
a
input
2
abcab
output
aab
input
3
bcabcbaccba
output
aaabb
Note

In the first sample, one can choose the subsequence {3} and form a string "a".

In the second sample, one can choose the subsequence {1, 2, 4} (symbols on this positions are 'a', 'b' and 'a') and rearrange the chosen symbols to form a string "aab".

分析:贪心,在选取当前字符后最多隔m个取一个最小的(坐标尽量靠后);

   这样选完后扫一遍字符串,那些没有被选取且不是当前答案里最大的字符也能加入答案;

   最后排序即可;

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, ls[rt]
#define Rson mid+1, R, rs[rt]
const int maxn=2e5+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p;p=p*p;q>>=;}return f;}
inline ll read()
{
ll x=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,k,t,vis[maxn];
struct node
{
char x;
int pos;
node(char _x,int _pos):x(_x),pos(_pos){}
bool operator<(const node&p)const
{
return x==p.x?pos>p.pos:x<p.x;
}
};
char a[maxn],ma;
string ans;
set<node>pq;
int main()
{
int i,j;
scanf("%d%s",&n,a);
int len=strlen(a),pre=;
for(i=;i<n;i++)pq.insert(node(a[i],i));
i=n;
while()
{
node now=*pq.begin();
ans+=now.x;
ma=max(ma,now.x);
vis[now.pos]=;
for(j=pre;j<=now.pos;j++)pq.erase(node(a[j],j));
pre=now.pos+;
int cnt=;
for(j=i;j<len&&j-now.pos<=n;j++)
{
i=j;
cnt=j-now.pos;
pq.insert(node(a[j],j));
}
i++;
if(cnt<n)break;
}
for(i=;a[i];i++)if(!vis[i]&&a[i]<ma)ans+=a[i];
sort(ans.begin(),ans.end());
cout<<ans<<endl;
//system("Pause");
return ;
}