ICode9

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

CF1458D Flip and Reverse

2020-12-20 15:33:34  阅读:244  来源: 互联网

标签:Reverse int 路径 Flip -- while CF1458D include 欧拉


一个\(01\)串,可以如此操作:选择一个\(0,1\)出现次数相同的子串,将其翻转并取反。

问经过任意次操作之后的字典序最小的字符串是什么。

\(n\le 5*10^5\)


神仙转化。

把\(0\)视作\(+1\),把\(1\)视作\(-1\),做个前缀和\(s_i\)。连边\((s_i,s_{i+1})\)。

原来的字符串相当于这个图上的一条欧拉路径。

思考下一个操作意味着什么:相当于找到欧拉路径上的一个环,将其反向并翻转。

然后可以发现任意两个合法的欧拉路径可以通过这个操作转化,也就是:任意合法的欧拉路径都是能够形成的字符串。

然后就是个图上找最小字典序欧拉路径的问题。

两种做法:经典做法,直接递归做,回溯的时候把点丢入栈中,最后倒序输出栈中的点,做之前把边从小到大排序;或者也可以直接贪心选,但是要保证现在走的这条边不是桥。由于这题的特殊性,这个东西是比较好判断的。


using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500005
int n;
char s[N];
int _e[N+N];
#define e(x) (_e[(x)+N])
int q[N],k;
void dfs(int x){
	while (e(x)){
		e(x)--;
		dfs(x+1);
	}
	while (e(x-1)){
		e(x-1)--;
		dfs(x-1);
	}
	q[++k]=x;
}
int main(){
	freopen("in.txt","r",stdin);
	int T;
	scanf("%d",&T);
	while (T--){
		scanf("%s",s+1);
		n=strlen(s+1);
		int x=0;
		for (int i=1;i<=n;++i){
			int y=x+(s[i]=='0'?1:-1);			
			e(min(x,y))++;
			x=y;			
		}
		dfs(0);
		x=0;
		for (--k;k;--k){
			int y=q[k];
			if (x+1==y)
				putchar('0');
			else
				putchar('1');
			x=y;
		}
		putchar('\n');
	}
	return 0;
}

标签:Reverse,int,路径,Flip,--,while,CF1458D,include,欧拉
来源: https://www.cnblogs.com/jz-597/p/14163674.html

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

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

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

ICode9版权所有