Authors have come up with the string ss consisting of nn lowercase Latin letters.
You are given two permutations of its indices (not necessary equal) pp and qq (both of length nn). Recall that the permutation is the array of length nn which contains each integer from 11 to nn exactly once.
For all ii from 11 to n−1n−1 the following properties hold: s[pi]≤s[pi+1]s[pi]≤s[pi+1] and s[qi]≤s[qi+1]s[qi]≤s[qi+1]. It means that if you will write down all characters of ss in order of permutation indices, the resulting string will be sorted in the non-decreasing order.
Your task is to restore any such string ss of length nn consisting of at least kk distinct lowercase Latin letterswhich suits the given permutations.
If there are multiple answers, you can print any of them.
Input
The first line of the input contains two integers nn and kk (1≤n≤2⋅105,1≤k≤261≤n≤2⋅105,1≤k≤26) — the length of the string and the number of distinct characters required.
The second line of the input contains nn integers p1,p2,…,pnp1,p2,…,pn (1≤pi≤n1≤pi≤n, all pipi are distinct integers from 11 to nn) — the permutation pp.
The third line of the input contains nn integers q1,q2,…,qnq1,q2,…,qn (1≤qi≤n1≤qi≤n, all qiqi are distinct integers from 11 to nn) — the permutation qq.
Output
If it is impossible to find the suitable string, print "NO" on the first line.
Otherwise print "YES" on the first line and string ss on the second line. It should consist of nn lowercase Latin letters, contain at least kk distinct characters and suit the given permutations.
If there are multiple answers, you can print any of them.
Example
Input
3 2
1 2 3
1 3 2
Output
YES
abb
题意:给你一段序列,让你求最少用k个字母构成一个字符串,这个字符串满足 s[p[i]]<=s[p[i+1]] s[q[i]]<=s[q[i+1]];
题目思路:
首先建图,a->b建边 表示是s[a]<=s[b] 然后求强连通分量 ,任何一个强连通分量内 绝对字母都一样
然后 对强连通分量进行缩点,判断一下强连通分量的个数如果<k ,那么问题无解,如果<=k,他说至少用k个字母,那咱们就用k个字母,而且强连通分量之间是单向联通的关系.所以拓扑图排序一下,然后将前k-1个不同,后面全都相同即可.
//#include <bits/stdc++.h>
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
#pragma GCC optimize(2)
typedef long long ll;
typedef unsigned long long ull;
const int mod=1000;
const int maxn=1e6+5;
const ll INF=100000000000005;
using namespace std;
ll n,m,p;
int head[maxn];
int head1[maxn];
ll cnt=0,cnt1=0;
struct node{
int e,next;
}edge[maxn],edge1[maxn];
int dfn[maxn],low[maxn];//dfs序号 他能连接到的最小根节点
int st[maxn],s=0;//栈
int sct[maxn],szsc[maxn],scc=0;//强连通分量所属,强连通分量个数
int inst[maxn];//标记是否在栈中
int cot=0;//标记DFS序
int res[maxn];
int in[maxn];
int vis[maxn];
void addedge1(int u,int v)
{
edge1[cnt1].e=v;
edge1[cnt1].next=head1[u];
head1[u]=cnt1++;
}
void addedge(int u,int v)
{
edge[cnt].e=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void Tarjan(int u)
{
st[++s]=u;inst[u]=1;
low[u]=dfn[u]=++cot;
for(int i=head[u];~i;i=edge[i].next)
{
int e=edge[i].e;
if(!dfn[e])
{
Tarjan(e);
low[u]=min(low[u],low[e]);
}
else if(inst[e])
low[u]=min(low[u],dfn[e]);
}
if(low[u]==dfn[u])
{
scc++;
while(1)
{
int x=st[s--];
inst[x]=0;
sct[x]=scc;
if(x==u) break;
}
}
}
void To_order()
{
int z=0;
queue<int>q;
for(int i=1;i<=scc;i++)
if(!in[i]) q.push(i);
while(!q.empty())
{
int u=q.front();q.pop();
if(z<m-1) res[u]=z++;
else res[u]=z;
for(int i=head1[u];~i;i=edge1[i].next)
{
int e=edge1[i].e;
in[e]--;
if(!in[e]) q.push(e);
}
}
printf("YES\n");
for(int i=1;i<=n;i++)
{
char ch=res[sct[i]]+'a';
printf("%c",ch);
}
printf("\n");
}
ll a[maxn];
ll b[maxn];
int main()
{
memset(head,-1,sizeof(head));
memset(head1,-1,sizeof(head1));
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
for(int i=1;i<=n-1;i++){
addedge(a[i],a[i+1]);
addedge(b[i],b[i+1]);
}
for(int i=1;i<=n;i++) if(!dfn[i])
Tarjan(i);
for(int i=1;i<=n;i++)
{
for(int k=head[i];~k;k=edge[k].next)
{
int e=edge[k].e;
if(sct[i]!=sct[e]){
addedge1(sct[i],sct[e]);
in[sct[e]]++;
}
}
}
if(m>scc) printf("NO\n");
else To_order();
}
/***
样例测试空间:
6
5
1 2
2 3
3 1
3 5
2 6
***/
同样例题: