CF1458D Flip and Reverse 建图+欧拉路

这篇博客探讨了一种将0视为-1,1视为+1的方法来处理前缀和,并通过转换和翻转区间来解决相关问题。文章通过举例解释了如何理解这种操作,并转化为图论问题,指出合法的翻转条件。博主通过贪心策略给出了AC代码实现,实现了在给定限制下的区间翻转操作。
CF1458D Flip and Reverse

伟大的人类智慧

把 0 看作 -1 ,把 1 看作 +1 ,计算前缀和

我们可以发现先转换再翻转一个区间,就是翻转他们的前缀和区间。(可以画一个函数图像来理解),那么答案就变成了可以任意翻转区间 [ l , r ] , s l = s r [l,r],s_l=s_r [l,r],sl=sr ,求

如序列 { a i } \{a_i\} {ai} 1   0   0   1   0   1 1\ 0\ 0\ 1\ 0\ 1 1 0 0 1 0 1 ,则前缀和序列 { s i } \{s_i\} {si} 0   1   0   − 1   0   − 1   0 0\ 1\ 0\ -1\ 0\ -1\ 0 0 1 0 1 0 1 0 (第 0 位为 0

转换再翻转 { a i } \{a_i\} {ai} 的区间 [ 1 , 4 ] [1,4] [1,4] ,就相当于翻转 { s i } \{s_i\} {si} 的区间 [ 0 , 4 ] [0,4] [0,4] ,第 0 位值不变,那么 { s i } \{s_i\} {si} 第 0 位的下一位就变成了原来 { s i } \{s_i\} {si} 的第 3 位。

我们把前缀和序列的每一位看成点,相邻(位置)的点连边,就形成了一条链。因为可以翻转区间,原本的边 k − > k + 1 k->k+1 k>k+1 ,翻转区间后, k k k 的下一个数就可能变成 k − 1 k-1 k1 了(见上面那个例子)。这就启发我们相邻(值)的点之间可以直接到达。这样就把翻转操作变成了跳点。显然不是任意的 k − > k − 1 k->k-1 k>k1 都是合法的。

合法条件是什么呢?

从 k 走到 k-1 ,当且仅当没有 k+1 或者 k 和 k-1 之间有至少 2 条边。(想想这是为什么

最后贪心的填每位(网上题解说走一条欧拉路其实一个意思),于是就做完啦。

//AC代码
#include<bits/stdc++.h>
using namespace std;
int T,n,sum,val[1000100];
char s[500100];
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%s",s),n=strlen(s),sum=0;
		for(int i=0;i<n;i++)s[i]=(s[i]=='1'?1:-1);
		for(int i=0;i<n;i++)val[max(sum,sum+s[i])+n]++,sum+=s[i];
		for(int i=0,j=n;i<n;i++){
			if(val[j]>=2)putchar('0'),val[j--]--;
			else if(val[j+1]>=2)putchar('1'),val[++j]--;
			else if(val[j])putchar('0'),val[j--]--;
			else if(val[j+1])putchar('1'),val[++j]--;
			else{puts("FAIL");return 0;} 
		}puts("");
		for(int i=0;i<=2*n;i++)val[i]=0;
	}
	return 0;
}
### RS触发器(RS Flip - Flops) RS触发器是一种基本的双稳态电路,有两个输入(R和S)和两个互补输出(Q和$\overline{Q}$)。其特性方程为: - 当$S = 1$,$R = 0$时,$Q^{n + 1} = 1$,即置位状态,使输出$Q$为高电平。 - 当$S = 0$,$R = 1$时,$Q^{n + 1} = 0$,即复位状态,使输出$Q$为低电平。 - 当$S = 0$,$R = 0$时,$Q^{n + 1} = Q^{n}$,保持原状态不变。 - 当$S = 1$,$R = 1$时,输出状态不确定,这种情况在实际应用中应避免。 以下是一个简单的Verilog代码示例来实现RS触发器: ```verilog module rs_flip_flop( input wire R, input wire S, output reg Q, output wire Q_bar ); assign Q_bar = ~Q; always @(*) begin if (S == 1 && R == 0) Q = 1; else if (S == 0 && R == 1) Q = 0; else if (S == 0 && R == 0) Q = Q; else Q = 1'bx; // 不确定状态 end endmodule ``` ### D触发器(D Flip - Flops) D触发器只有一个数据输入(D)和一个时钟输入(clk),其输出(Q)在时钟信号的有效边沿(上升沿或下降沿)将输入数据D保存下来。特性方程为$Q^{n + 1} = D$。 Verilog代码示例: ```verilog module d_flip_flop( input wire clk, input wire D, output reg Q ); always @(posedge clk) begin Q <= D; end endmodule ``` ### JK触发器(JK Flip - Flops) JK触发器有两个输入(J和K)和一个时钟输入(clk),它是对RS触发器的改进,消除了RS触发器中$S = 1$,$R = 1$时的不确定状态。其特性如下: - 当$J = 0$,$K = 0$时,$Q^{n + 1} = Q^{n}$,保持原状态。 - 当$J = 0$,$K = 1$时,$Q^{n + 1} = 0$,复位状态。 - 当$J = 1$,$K = 0$时,$Q^{n + 1} = 1$,置位状态。 - 当$J = 1$,$K = 1$时,$Q^{n + 1} = \overline{Q^{n}}$,翻转状态。 Verilog代码示例: ```verilog module jk_flip_flop( input wire clk, input wire J, input wire K, output reg Q ); always @(posedge clk) begin if (J == 0 && K == 0) Q <= Q; else if (J == 0 && K == 1) Q <= 0; else if (J == 1 && K == 0) Q <= 1; else if (J == 1 && K == 1) Q <= ~Q; end endmodule ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值