传送门

题意:

你需要输出一个长度为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. 【Oracle】dump函数用法

    Oracle dump函数的用法 一.函数标准格式: DUMP(expr[,return_fmt[,start_position][,length]]) 基本参数时4个,最少可以填的参数是0个.当完全 ...

  2. 【Android初级】如何实现一个“模拟后台下载”的加载效果(附源码)

    在Android里面,后台的任务下载功能是非常常用的,比如在APP Store里面下载应用,下载应用时,需要跟用户进行交互,告诉用户当前正在下载以及下载完成等. 今天我将通过使用Android的原生控 ...

  3. GIT常用命令:

    1.安装好Git之后,点击鼠标右键即可看到有Git bush选项,点击即可进入Git命令行操作. 2.使用命令: git  config  --global user.name "lyh&q ...

  4. Bitter.Core系列三:Bitter ORM NETCORE ORM 全网最粗暴简单易用高性能的 NETCore ORM 之 示例模型创建

    在具体数据库操作之前,我们先准备好四张表以及相对应数据库操作模型: 学生表,年级表,班级表,学分表.示例数据库表,如下代码(MSSQL 为例) --学生表 CREATE TABLE t_student ...

  5. moco框架实现重定向

    一.重定向到百度 1.代码 2.运行结果 因为没哟填写别的,浏览器输入路径: localhost:8888/redirect 点击回车,跳转到百度 二.跳转到自己的网站 1.代码 2.运行结果 输入准 ...

  6. UNIX DOMAIN SOCKETS IN GO unix域套接字

    Unix domain sockets in Go - Golang News https://golangnews.org/2019/02/unix-domain-sockets-in-go/ pa ...

  7. Mysql 不能使用逗号的情况

    不存在逗号的情况: 联合查询: 1.UNION SELECT * FROM ((SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4) ...

  8. POSTGIS

    https://blog.csdn.net/qq_35732147/article/details/85256640 官方文档:http://www.postgis.net/docs/ST_Buffe ...

  9. PowerQuery合并查询原理

    PowerQuery的合并查询比Excel中的VLOOKUP更加强大,下面对查询的类型做一个梳理, 1.左外部(第一个中的所有行,第二个中的匹配行):用左边表内的所有行去右边找它的匹配项 2.右外部( ...

  10. 单机模拟配置Eureka集群

    首先先提醒单机部署的重要点 如果使用一个ip地址(适用于单网卡)每个eureka实例使用不同的域名映射到同一个IP 如果每个eureka实例使用不同的IP(多网卡),要确保这些IP要都表示本地 本文假 ...