传送门

题意:

你需要输出一个长度为n的字符序列(由小写字母组成),且这个字符串中至少包含k个不同的字符。另外题目还有要求:给你两个长度为p和q的序列,设字符序列存在s中

那么就会有s[Pi]<=s[P(i+1)]   (i<p)

     s[Qi]<=s[Q(i+1)]   (i<q)   如果你能找出来满足这些条件的字符串s,就输出YES和s,否则输出NO

这会得到一个非递减字符串

题解:

因为最后的结果是一个非递减字符串,那么肯定对整个字符串s,会有s[i]<=s[i+1] (0<=i<strlen(s)-1)

那么这样的话,只有当Pi>P(i+1)或者Qi>Q(i+1)的时候,才会影响字符串在[P(i+1),Pi]或者[Q(i+1),Qi]的取值,这一段区间内的字符肯定要相等

因为题目上要求字符串s至少要有k个不同的字符,所以只要不遇到上面这种情况,那么每一个位置的字符都要比上一个字符大(我们这里是先用a,再用b等等)

所以我们只需要注意Pi>P(i+1)或者Qi>Q(i+1)这种区间就可以了

想到这里正解就出来了,对每个P[i]找到最小的jjj,使得P[j]的位置在Q中位于P[i]的后方(为了方便,认为i自身也是一个合法的jjj),那么P[j..i]就必须同字母。如果两个同字母段相交,那么合并起来的整一段都必须同字母,因此处理完所有字母段再扫一遍,把相交的同字母段合并。最后看看有没有k段,贪心地让不同字母段用不同的字母即可,复杂度O(n)

如果用到了字符z,但是序列s还没有写完,那么剩下的全部位置输出z

如果抛开题目去看,你输出一个长为n的序列,如果这个序列中只包含一个字符,那么除了不满足k个不同字符的要求外,其他条件都满足

还有一种方法,P[i]]向P[i−1]连边,Q[i]则Q[i−1]连边,边(x,y)就表示x位置上的字母必须不小于y位置,那么一个强连通分量的所有位置必须同字母,一遍tarjan即可

我原来写了一个,但是过于暴力,T了T_T

T代码:

 1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 #include<algorithm>
5 #include<vector>
6 #include<queue>
7 using namespace std;
8 const int maxn=2e5+5;
9 const int INF=0x3f3f3f3f;
10 typedef long long ll;
11 //vector<int>w[maxn];
12 int a[maxn],b[maxn],v[maxn],w[maxn];
13 int main()
14 {
15 int n,k;
16 //memset(v,INF,sizeof(v));
17 scanf("%d%d",&n,&k);
18 for(int i=1; i<=n; ++i)
19 {
20 scanf("%d",&a[i]);
21 }
22 for(int i=1; i<=n; ++i)
23 scanf("%d",&b[i]);
24 for(int i=1; i<n; ++i)
25 {
26 if(a[i+1]<a[i])
27 {
28 v[a[i+1]]=max(v[a[i+1]],a[i]);
29 }
30 }
31 for(int i=1; i<n; ++i)
32 {
33 if(b[i+1]<b[i])
34 {
35 v[b[i+1]]=max(v[b[i+1]],b[i]);
36 }
37 }
38 int ans=0,flag=0;
39 for(int i=1; i<=n; ++i)
40 {
41 if(w[i]==0)
42 {
43 if(v[i]==0)
44 {
45 w[i]='a'+ans++;
46 }
47 else
48 {
49 for(int j=i; j<=v[i]; ++j)
50 w[j]='a'+ans;
51 ans++;
52 //i=v[i];
53 }
54 }
55 else
56 {
57 if(v[i]==0)
58 {
59 continue;
60 }
61 else
62 {
63 for(int j=i+1; j<=v[i]; ++j)
64 w[j]=w[i];
65 //i=v[i];
66 }
67 }
68 }
69 if(ans<k) flag=1;
70 if(!flag)
71 {
72 printf("YES\n");
73 for(int i=1; i<=n; ++i)
74 {
75 if(i!=n) printf("%c",w[i]);
76 else printf("%c\n",w[i]);
77 }
78 }
79 else
80 {
81 printf("NO\n");
82 }
83 return 0;
84 }

正解:

 1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<queue>
5 #include<cmath>
6 #include<string.h>
7 #include<set>
8 #define LL long long
9 using namespace std;
10 LL read( )
11 {
12 LL sum=0;char c=getchar( );bool f=0;
13 while(c<'0' || c>'9') {if(c=='-') f=1;c=getchar( );}
14 while(c>='0' && c<='9') {sum=sum*10+c-'0';c=getchar( );}
15 if(f) return -sum;
16 return sum;
17 }
18 const int N=200005;
19 int n,m,P[N],Q[N],pos[N],L[N],bel[N];
20 char ans[N];
21 int main( )
22 {
23 int i,j,k;
24 n=read( );m=read( );
25 for(i=1;i<=n;i++) P[i]=read( ),pos[P[i]]=i;
26 for(i=1;i<=n;i++) Q[i]=read( );
27 for(k=n,i=n;i>=1;i--) j=pos[Q[i]],k=min(k,j),L[j]=k;
28 for(j=1,k=n,i=n;i>=1;i--)
29 {
30 k=min(k,L[i]);bel[i]=j;
31 if(k==i) j++;
32 }
33 if(bel[1]<m) {puts("NO");return 0;}
34 puts("YES");
35 for(j=-1,i=1;i<=n;i++)
36 {
37 if(bel[i]!=bel[i-1]) j++;
38 ans[P[i]]='a'+min(25,j);
39 }
40 for(i=1;i<=n;i++) printf("%c",ans[i]);
41 return 0;
42 }

Codeforces Round #582 (Div. 3) F. Unstable String Sort的更多相关文章

  1. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  2. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  3. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

  4. 贪心 Codeforces Round #303 (Div. 2) B. Equidistant String

    题目传送门 /* 题意:找到一个字符串p,使得它和s,t的不同的总个数相同 贪心:假设p与s相同,奇偶变换赋值,当是偶数,则有答案 */ #include <cstdio> #includ ...

  5. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  6. Codeforces Round #582 (Div. 3)-G. Path Queries-并查集

    Codeforces Round #582 (Div. 3)-G. Path Queries-并查集 [Problem Description] 给你一棵树,求有多少条简单路径\((u,v)\),满足 ...

  7. Codeforces Round #376 (Div. 2)F. Video Cards(前缀和)

    题目链接:http://codeforces.com/contest/731/problem/F 题意:有n个数,从里面选出来一个作为第一个,然后剩下的数要满足是这个数的倍数,如果不是,只能减小为他的 ...

  8. Codeforces Round #271 (Div. 2) F题 Ant colony(线段树)

    题目地址:http://codeforces.com/contest/474/problem/F 由题意可知,最后能够留下来的一定是区间最小gcd. 那就转化成了该区间内与区间最小gcd数相等的个数. ...

  9. Codeforces Round #479 (Div. 3) F. Consecutive Subsequence (简单dp)

    题目:https://codeforces.com/problemset/problem/977/F 题意:一个序列,求最长单调递增子序列,但是有一个要求是中间差值都是1 思路:dp,O(n)复杂度, ...

随机推荐

  1. 【Flutter】功能型组件之对话框详解

    前言 对话框本质上也是UI布局,通常一个对话框会包含标题.内容,以及一些操作按钮,为此,Material库中提供了一些现成的对话框组件来用于快速的构建出一个完整的对话框. 接口描述 // 1. Ale ...

  2. Tomcat-8 安装和配置

    JDK 安装: # 选择版本: yum list all | grep jdk # 安装openjdk-1.8.0: yum install java-1.8.0-openjdk.x86_64 -y ...

  3. python3.6安装教程

    Python代码要运行,必须要有Python解释器.Python3.x的版本是没有什么区别的,这里以3.6版本来演示安装的过程.这里只介绍Windows环境下的安装. 下载安装程序 Python官方的 ...

  4. ctfhub技能树—RCE—过滤目录分隔符,过滤运算符

    过滤目录分隔符 打开靶机 查看页面信息 查询当前目录下文件结构 进入flag_is_here目录 127.0.0.1;cd flag_is_here 127.0.0.1||ls 执行之后发现还是在当前 ...

  5. 1.5V转5V的最少电路的芯片电路图

    PW5100满足1.5V转5V的很简洁芯片电路,同时达到了最少的元件即可组成DC-DC电路1.5V转5V的升压转换器系统. PW5100在1.5V转5V输出无负载时,输入效率电流极低,典型值10uA. ...

  6. Python语言程序设计---函数的定义与使用

    推荐一个Python学习交流的q群:610380249 在学习Python的过程中,有什么不懂的问题都可以发群里,一起讨论. 1 函数的理解和定义 函数是一段代码的表示,所指定的参数是一种占位符,如果 ...

  7. Linux下pcstat安装踩坑教程

    首先安装golang 1.进入官方链接下载对应自己系统版本的Golang安装包:https://dl.google.com/go/go1.13.4.linux-amd64.tar.gz root@ub ...

  8. python_3 装饰器参数之谜

    装饰器参数之谜 之前已经初步了解过装饰器了,知道了装饰器可以"偷梁换柱",在不改变函数的调用方式和函数内容的时候,而把函数的功能偷偷地修改. 那么问题来了,如果被修改的函数中有参数 ...

  9. 任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行

    任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行 多线程 - 廖雪峰的官方网站 https://www.liaoxuefeng ...

  10. 解决windows git乱码问题

    在windows中打开git bash git config --global i18n.commitencoding utf-8       设置提交日志使用utf-8 git config --g ...