首页 > 其他分享 >AGC022E Median Replace

AGC022E Median Replace

时间:2024-08-16 16:17:11浏览次数:14  
标签:11 1S Median Replace iff AGC022E 变成 合法 dp

传送门

题意:给定长度为奇数的 01? 串,问多少种填法使得串可以变成 \(1\)。一次操作定义为把连续三个数变成它们的中位数。

这种计数题可以先考虑怎么判定一个串是否可以变成 \(1\),称作合法。

根据人类智慧,可以想到 \(000S\) 合法 \(\iff\) \(0S\) 合法,进而启示我们考虑串 \(S\) 的前几位,看它与什么串的答案等价。

观察发现:

  1. \(01S \iff S\);

  2. \(001S \iff 0S\);

  3. \(000S \iff 0S\);

  4. \(101S \iff 1S\);

  5. \(1001S \iff 10S\);

  6. \(1000S \iff 10S\);

  7. \(11S\) 一定合法。

第七条是非常显然的,只需证明前六条;而前六条性质从右到左同样非常显然,只需证明前六条的 \(\Rightarrow\) 方向。

引理:\(1S\) 合法 \(\iff\) \(S\) 可以变成 \(01/10/11\)。

证明:\(\Leftarrow\) 显然,只证明 \(\Rightarrow\)。

考虑 \(1S\) 要变成 \(1\),最后三个数来自 \(1S\) 的哪些部分。

  1. \(1+S_1+S_2\),因为能变成 \(1\),所以 \(S_1,S_2\) 中必有一个 \(1\)。

  2. \(1S_1+S_2+S_3\)。若 \(1S_1\) 对应的是 \(0\),则 \(S_2,S_3\) 都能变成 \(1\),显然 \(S=S_1S_2S_3\) 能变成 \(10/01/11\)。

    否则 \(1S_1\) 对应变成 \(1\),根据归纳法,\(S_1\) 能变成 \(01/10/11\),可以发现无论 \((S_2,S_3)=(1,0)/(0,1)/(1,1)\),\(S\) 也都能变成 \(01/10/11\)。


引理证毕,下面开始证明。

  1. \(01S\) 合法,考虑 \(01S\) 倒数第二步时的三个数对应原本的哪三段。

    • \(0+1+S\),这表示因为 \(0,1,\text{S 变成的数}\) 要能变成 \(1\),所以 \(S\) 可以变成 \(1\)。

    • \(0+1S_1+S_2\),因为有一个 \(0\),所以 \(1S_1,S_2\) 都要能变成 \(1\)。根据引理,\(S_1\) 能变成 \(01/10/11\),所以 \(S_1S_2\) 一起能变出两个 \(1\) 一个 \(0\),\(S\) 合法。

    • \(01S_1+S_2+S_3\)。如果 \(01S_1\) 变成的是 \(0\),则 \(S_2,S_3\) 都变成 \(1\),\(S=S_1S_2S_3\) 可以变成 \(\cdots 11\),\(S\) 合法。

      否则 \(01S_1\) 归纳法证明。

上面六条都可以类似证明,可自行练习。
另外这里可以偷个懒:\(000S\) 合法 \(\Rightarrow 001S\) 合法 \(\iff\) \(0S\) 合法。


在证明了上面六条之后,我们可以建立一个这样的自动机:接受的信号类型只有 \(0,1\) 两种。一共七个状态,每个状态对应一个 \(01\) 串。每个状态接受信号的目的地,就根据上面的定理。

例如 \(0\) 接受了信号 \(1\) 就回到代表 "空" 的结点,因为 \(01S\iff S\)。
例如 \(00\) 接受了信号 \(0/1\) 就回到代表 "0" 的结点,因为 \(000S/001S\iff 0S\)。

另外,代表 "11" 的结点是终止状态。

于是我们可以在自动机上 DP。\(dp[i][j]\) 表示填了前 \(i\) 个字符,位于自动机上结点 \(j\) 的方案总数。把 \(id(x)\) 记为 \(x\) 对应的自动机结点编号。注意转移的时候不能从 \(dp[i][id(11)]\) 出发转移。

\(ans=dp[len][id(1)]+\sum dp[i][id(11)]\times pow\)。

\(dp[len][id(1)]\) 很好理解,填完全部之后如果你的串合法等价于 \(1\) 合法,当然就合法;后面那一串是因为你的串等价于 \(11\cdots\) 时,是一定合法的,只需要统计 \(\cdots\) 里面有多少个问号,乘一个二的幂就行了。

点击查看代码
#include <bits/stdc++.h> 

using namespace std;
typedef long long ll;
const int N = 3e5 + 5, MOD = 1e9 + 7;

string s;
ll dp[N][8] = {{}};
int e[10][2];
ll ans = 0;

int main() {
//	freopen("1.in", "r", stdin);
//	freopen("1.out", "w", stdout);
	cin >> s;
	
	if (s.size() == 1) {
		if (s == "1" || s == "?")
			cout << 1 << endl;
		else
			cout << 0 << endl;
		return 0;
	} 
	
	e[1][0] = 2;
	e[1][1] = 4;
	e[2][1] = 1;
	e[2][0] = 3;
	e[3][0] = e[3][1] = 2;
	e[4][0] = 5;
	e[4][1] = 7;
	e[5][0] = 6;
	e[5][1] = 4;
	e[6][0] = e[6][1] = 5;
	
	dp[0][1] = 1;
	for (int i = 0; i < s.size(); i++) {
		for (int j = 1; j <= 6; j++) {
			if (s[i] != '0')
				dp[i + 1][e[j][1]] = (dp[i + 1][e[j][1]] + dp[i][j]) % MOD;
			if (s[i] != '1')
				dp[i + 1][e[j][0]] = (dp[i + 1][e[j][0]] + dp[i][j]) % MOD;
		}
	}
	
	ans = dp[s.size()][4];
	for (ll i = s.size() - 1, pw = 1; i >= 0; i--) {
		ans = (ans + dp[i + 1][7] * pw % MOD) % MOD;
		if (s[i] == '?')
			pw = pw * 2 % MOD; 
	}
	cout << ans << endl;
	return 0;
}

标签:11,1S,Median,Replace,iff,AGC022E,变成,合法,dp
From: https://www.cnblogs.com/FLY-lai/p/18362946

相关文章

  • F.regexp_replace
     F.regexp_replace是PySpark中用于在DataFrame的列中执行正则表达式替换操作的函数。它可以用来匹配字符串中的某些模式,并用指定的字符串替换这些模式。使用场景清理数据中的特定字符或模式(如去除特殊字符、替换特定的子字符串)。标准化数据格式(如替换日期格式、移......
  • c语言替换字符串 Replace the first ‘oldstr‘ with ‘newstr‘ in ‘srcstr‘
    #include<string.h>#include<stdlib.h>#include<stdio.h>#include<time.h>#include<ctype.h>#include<sys/stat.h>voidgetdate(char*datestr,char*format){ time_tnnowtime=time(NULL); structtm*ptmTemp=loc......
  • CF1999F.Expected Median 题解
    一.前言这是一道很有趣的数学题目,用到了逆元和组合数学,非常适合新手练手。二.题目大意:给出一个长度为\(n\)的\(01\)数组。找出所有长度为\(k\)的子序列的中位数,求出其和。妥妥的数学题~三.分析首先考虑对答案的贡献。很明显,只有\(1\)作为中位数时才会做出贡献,于是......
  • 高并发场景下慎用replace into来进行数据库操作
    概述REPLACEINTO操作虽然简单易用,但在使用时需要注意其带来的各种影响,包括锁粒度、性能开销、数据一致性、事务处理和并发控制等方面。在高并发和大数据量环境下,建议评估其性能影响,并根据实际需求选择合适的替代方案,如使用INSERT...ONDUPLICATEKEYUPDATE来避免不必......
  • AT_abl_e Replace Digits 题解
    题目传送门前置知识线段树解法需要维护区间信息,考虑使用线段树维护。预处理出\(\overline{xx\dotsx}\),其中\(x\in\{1,2,3,4,5,6,7,8,9\}\),便于区间赋值。然后就是普通的线段树板子了。代码#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#de......
  • PHP中preg_replace函数解析
    preg_replace—执行一个正则表达式的搜索和替换mixedpreg_replace(mixed$pattern,mixed$replacement,mixed$subject)搜索subject中匹配pattern的部分,以replacement进行替换。常见于CTF竞赛中web题目中1、/g表示该表达式将用来在输入字符串中查找所有可能的匹配,返......
  • 题解:CF1349B Orac and Medians
    洛谷|CF刷一些CF2000,进行一个录的记。思路记录首先观察到数列里的数不能凭空产生,所以初始序列必须含\(k\)。由于两个数的中位数是较小的那个,所以只要有一个与数列里的\(k\)相邻且比\(k\)大的数,就可以扩展到整个序列。发现可以把第二条推广一下,不必要和\(k\)相邻,因......
  • MYSQL中replace into的用法
    今天在编程的时候,学习了replaceinto的用法,真的很好用,是insertinto的增强版。在向表中插入数据时,我们经常会遇到这样的情况:1、首先判断数据是否存在;2、如果不存在,则插入;3、如果存在,则更新。###项目成本案例:::::  1IntegerupdateTransport(Reimbursementreimbursement);......
  • uniapp报错 TypeError: Cannot read properties of undefined (reading ‘replace‘)
      欢迎关注我......
  • Java 中的字符串替换方法详解:replace, replaceAll 和 replaceFirst
    在Java中,字符串的替换是一种常见的操作,特别是在处理文本和格式化输出时。Java提供了几种不同的方法来实现字符串替换,其中包括replace,replaceAll和replaceFirst。本文将详细讨论这些方法的用法、区别以及示例。1.replace(CharSequencetarget,CharSequencereplaceme......