[CSP校内集训]rank

Posted chtholly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CSP校内集训]rank相关的知识,希望对你有一定的参考价值。

题意

给出一个字符串后缀排序之后的数组(sa_i),求原字符串(字典序最小),无解输出-1

思路

显然从(rk_1)开始填字符是可以保证字符单调不降的

找到(sa)值相邻的两个位置,现在需要知道(rk_i)(rk_{i+1})是否可以填相邻字符;当它们填相同字符时需要比较后一位,如果相对关系相同则可行(因为后一位默认已经成立)

举个栗子:(4,2,3,1),查看4能不能和3填同一个字符,则判断后一位2和1;而(4>3 && 2>1),所以可以相同

Code

#include<bits/stdc++.h>
#define N 200005
#define Min(x,y) ((x)<(y)?(x):(y))
#define Max(x,y) ((x)>(y)?(x):(y))
using namespace std;
typedef long long ll;
int n,a[N],loc[N];
bool sm[N];
char ans[N];

template <class T>
void read(T &x)
{
    char c; int sign=1;
    while((c=getchar())>'9'||c<'0') if(c=='-') sign=-1; x=c-48;
    while((c=getchar())>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48; x*=sign;
}

int main()
{
    freopen("rank.in","r",stdin);
    freopen("rank.out","w",stdout);
    read(n);
    for(int i=1;i<=n;++i) read(a[i]),loc[a[i]]=i;
    a[n+1]=0;//强调2333 
    for(int i=1;i<n;++i) sm[i+1]=(a[loc[i]+1]<a[loc[i+1]+1]);
    char now='a';
    ans[loc[1]]=now;
    for(int i=2;i<=n;++i)
    {
        if(!sm[i]) ++now;
        if(now>'z') {printf("-1");return 0;}
        ans[loc[i]]=now;
    }
    for(int i=1;i<=n;++i) putchar(ans[i]);
    return 0;
}

以上是关于[CSP校内集训]rank的主要内容,如果未能解决你的问题,请参考以下文章

[CSP校内集训]tree(期望DP)

[CSP校内集训]pestc(拓扑排序)

[CSP校内集训]矩形面积交(树状数组)

[CSP校内集训]贪吃蛇(阿尔法-贝塔剪枝)

校内集训(20170910)

2019.10.22 校内CSP%你赛