String Coloring

String Coloring (easy version)
This is an easy version of the problem. The actual problems are different, but the easy version is almost a subtask of the hard version. Note that the constraints and the output format are different.

You are given a string s consisting of n lowercase Latin letters.

You have to color all its characters one of the two colors (each character to exactly one color, the same letters can be colored the same or different colors, i.e. you can choose exactly one color for each index in s).

After coloring, you can swap any two neighboring characters of the string that are colored different colors. You can perform such an operation arbitrary (possibly, zero) number of times.

The goal is to make the string sorted, i.e. all characters should be in alphabetical order.

Your task is to say if it is possible to color the given string so that after coloring it can become sorted by some sequence of swaps. Note that you have to restore only coloring, not the sequence of swaps.

Input
The first line of the input contains one integer n(1n200)n (1≤n≤200) — the length of s.

The second line of the input contains the string s consisting of exactly n lowercase Latin letters.

Output
If it is impossible to color the given string so that after coloring it can become sorted by some sequence of swaps, print “NO” (without quotes) in the first line.

Otherwise, print “YES” in the first line and any correct coloring in the second line (the coloring is the string consisting of n characters, the i-th character should be ‘0’ if the i-th character is colored the first color and ‘1’ otherwise).

Examples

input
9
abacbecfd
output
YES
001010101
input
8
aaabbcbb
output
YES
01011011
input
7
abcdedc
output
NO
input
5
abcde
output
YES
00000

如果一個字符串可以分成兩個非遞減的子序列,則存在染色方案,染色方案爲把其中一個序列染爲1,另一個染爲0。因爲顯然同色的序列不能改變順序,不同顏色的序列的元素之間的順序可以任意改變。
(雖然代碼中的做法不一定能保證染色數最少,但是可以用反證法證明它是正確的)

#include<bits/stdc++.h>

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector<int>
#define pii pair<int,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<<x<<endl
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 205;
char str[N];
int n;
string s1, s2;
int ans[N];

int main() {
    n = qr();
    ss(str + 1);
    repi(i, 1, n) {
        if (s1.empty() || str[i] >= s1.back())s1.pb(str[i]), ans[i] = 1;
        else if (s2.empty() || str[i] >= s2.back())s2.pb(str[i]);
        else {
            puts("NO");
            return 0;
        }
    }
    puts("YES");
    repi(i, 1, n)printf("%d", ans[i]);
    return 0;
}

String Coloring (hard version)
This is a hard version of the problem. The actual problems are different, but the easy version is almost a subtask of the hard version. Note that the constraints and the output format are different.

You are given a string s consisting of n lowercase Latin letters.

You have to color all its characters the minimum number of colors (each character to exactly one color, the same letters can be colored the same or different colors, i.e. you can choose exactly one color for each index in s).

After coloring, you can swap any two neighboring characters of the string that are colored different colors. You can perform such an operation arbitrary (possibly, zero) number of times.

The goal is to make the string sorted, i.e. all characters should be in alphabetical order.

Your task is to find the minimum number of colors which you have to color the given string in so that after coloring it can become sorted by some sequence of swaps. Note that you have to restore only coloring, not the sequence of swaps.

Input
The first line of the input contains one integer n(1n2105)n (1≤n≤2⋅10^5) — the length of s.

The second line of the input contains the string s consisting of exactly n lowercase Latin letters.

Output
In the first line print one integer res(1resn)res (1≤res≤n) — the minimum number of colors in which you have to color the given string so that after coloring it can become sorted by some sequence of swaps.

In the second line print any possible coloring that can be used to sort the string using some sequence of swaps described in the problem statement. The coloring is the array c of length n, where 1≤ci≤res and ci means the color of the i-th character.

Examples

input
9
abacbecfd
output
2
1 1 2 1 2 1 2 1 2 
input
8
aaabbcbb
output
2
1 2 1 2 1 2 1 1
input
7
abcdedc
output
3
1 1 1 1 1 2 3 
input
5
abcde
output
1
1 1 1 1 1 

與easy version原理相同。
定義b[i]b[i]以第ii個字母結尾的序列的編號組成的序列。
因爲要滿足最小,所以對於每個待加入序列的字母,要將其添加到以小於等於該字母的最大字母結尾的序列。

#include<bits/stdc++.h>

#define si(a) scanf("%d",&a)
#define sl(a) scanf("%lld",&a)
#define sd(a) scanf("%lf",&a)
#define sc(a) scahf("%c",&a);
#define ss(a) scanf("%s",a)
#define pi(a) printf("%d\n",a)
#define pl(a) printf("%lld\n",a)
#define pc(a) putchar(a)
#define ms(a) memset(a,0,sizeof(a))
#define repi(i, a, b) for(register int i=a;i<=b;++i)
#define repd(i, a, b) for(register int i=a;i>=b;--i)
#define reps(s) for(register int i=head[s];i;i=Next[i])
#define ll long long
#define ull unsigned long long
#define vi vector<int>
#define pii pair<int,int>
#define mii unordered_map<int,int>
#define msi unordered_map<string,int>
#define lowbit(x) ((x)&(-(x)))
#define ce(i, r) i==r?'\n':' '
#define pb push_back
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define pr(x) cout<<#x<<": "<<x<<endl
using namespace std;

inline int qr() {
    int f = 0, fu = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-')fu = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        f = (f << 3) + (f << 1) + c - 48;
        c = getchar();
    }
    return f * fu;
}

const int N = 2e5 + 10;
char str[N];
int n;
int ans[N], tot;
vi b[30];

int main() {
    n = qr();
    ss(str + 1);
    repi(i, 1, n) {
        bool flag = false;
        repd(j, str[i] - 'a' + 1, 1)
            if (!b[j].empty()) {
                ans[i] = b[j].back();
                b[str[i] - 'a' + 1].pb(b[j].back());
                b[j].pop_back();
                flag = true;
                break;
            }
        if (!flag) {
            ans[i] = ++tot;
            b[str[i] - 'a' + 1].pb(tot);
        }
    }
    pi(tot);
    repi(i, 1, n)printf("%d ", ans[i]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章