ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF1458D Flip and Reverse

2021-07-03 21:36:20  阅读:204  来源: 互联网

标签:Reverse sum 路径 Flip CF1458D 字符串 对应 欧拉 前缀


一、题目

点此看题

二、解法

没有什么好的想法,就从图论的角度入手吧。

要根据题目特性来建图,首先要考虑把什么当做点的问题,如果把字符串的元素当成点是不好表示 子串必须包含同样数量的字符0与1 这个限制的。但是前缀和可以方便地表示这个限制,令 \(1\) 为 \(1\),\(0\) 为 \(-1\),那么如果 \(sum_l=sum_r\) 就说明这是一个可以操作的区间,那么我们把前缀和建成点

还要考虑怎么表示字符串里的元素,直接当成边建上去,对于元素 \(s_i\),将点 \(sum_{i-1}\) 和 \(sum_i\) 连一条标记为 \(s_i\) 的边,考虑原始字符串就对应了这张图里的某一条欧拉回路(因为要把所有的边访问完)

那么把转换和翻转操作对应到图上,因为有边相连的两个点编号相差 \(1\),所以这张图是很特别的。首先选出一条起点终点相同的路径,然后把沿路经过的边换方向即可,你会发现新的路径正好对应操作之后的字符串。

现在的问题是最小化字典序,有一个结论:所有欧拉路径都对应着操作后的合法字符串。考虑走到 \(x\) 之后出现了两种存在欧拉路径的选择 \(x-1\) 和 \(x+1\),因为都是欧拉路径所以往一边走一定能走回来,那么说明存在边 x-1->xx+1->x,如果应该走 x+1(即是对应原字符串的走法)那么是 x->x+1->x->x-1->x,可以通过操作换成 x->x-1->x->x+1->x,这正好对应走 x-1 的方法,虽然它并不对应原字符串但是合法的。

那么找到原图定起点定终点,经过标记字典序最小的欧拉回路即可,根据图的特性可以设计如下贪心。

  • 如果 x-1 走过去并且能走回来,那么无脑走 x-1 即可。
  • 否则 x-1 走过去就回不来了,那么走 x+1;如果走不了 x+1 是可以直接走 x-1 的。

代码非常好写,时间复杂度 \(O(n)\)

三、总结

套路:差分,前缀和。差分可以在区间打标记修改之类的问题使用,前缀和在有区间权值限制的问题使用。

如果要用图论,思考每类元素的意义(是建成边还是建成点),学会把限制建在图上是很重要的。

#include <cstdio>
#include <cstring>
const int M = 500005;
int read()
{
	int x=0,f=1;char c;
	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
	return x*f;
}
int T,n,a[2*M][2];char s[M];
void work()
{
    scanf("%s",s+1),n=strlen(s+1);
    int x=n;
    for(int i=1;i<=n;i++)
    {
        a[x][s[i]-'0']++;
        if(s[i]=='0') x--;
        else x++;
    }
    x=n;
    for(int i=1;i<=n;i++)
    {
        if(a[x][0] && a[x-1][1]) a[x][0]--,x--,printf("0");
        else if(a[x][1]) a[x][1]--,x++,printf("1");
        else a[x][0]--,x--,printf("0");
    }
    puts("");
}
signed main()
{
    T=read();
    while(T--) work();
}

标签:Reverse,sum,路径,Flip,CF1458D,字符串,对应,欧拉,前缀
来源: https://www.cnblogs.com/C202044zxy/p/14967601.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有