【数学】Monocarp and the Set—CF1886D

news/2024/12/2 13:25:37/

Monocarp and the Set—CF1886D
参考文章

思路

我们把添加数字的过程倒过来看,也就是对长度为 n n n 的数组一个一个删除数字。那么 ′ > ′ '>' > ′ < ′ '<' < ′ ? ′ '?' ? 就分别代表“删除最大的数字”、“删除最小的数字”、“删除一个不是最大值和最小值的数字”。

假设读入的字符串为 s s s。我们规定有效下标从 2 2 2 开始,因为这样 s i s_i si 代表的就是“数组中元素个数为 i i i 的时候从数组中删除一个元素”,符合人的思维,有利于后边写代码。

我们逆序遍历 s s s。如果 s i = ′ > ′ s_i~=~'>' si = > s i = ′ < ′ s_i~=~'<' si = <,那么显然这时候从数组中需要删除的数字一定是唯一的(删除最大值或最小值);如果 s i = ′ ? ′ s_i~=~'?' si = ?,因为这时候数组中元素个数为 n n n,所以除了不能删除最大值和最小值的话,我们能删除的数字的个数为 i − 2 i-2 i2

易知 r e s = res~=~ res =  “所有 s i = ′ ? ′ s_i~=~'?' si = ? 时的 i − 2 i-2 i2 的乘积”。

如果 s 2 = ′ ? ′ s_2~=~'?' s2 = ? ,我们不能从两个数字中挑选一个不是最大值也不是最小值的数字,所以这时候我们直接判定 r e s = 0 res~=~0 res = 0(为什么不用考虑 s 1 = ′ ? ′ s_1~=~'?' s1 = ? 的情况呢?因为题目规定第一次添加数字的时候不会“writes out a character”,所以自然也不用考虑数组中元素个数为 1 1 1 的时候要删除最大值、最小值还是一个不是最大值也不是最小值的数字)。

至于 m m m 次改变 s s s 字符串的操作,很容易可以想到这样即可:

int idx; cin >> idx; idx ++;
string cc; cin >> cc;
if (idx >= 3 && s[idx] == '?') {res = res / (idx - 2);
}
s[idx] = cc[0];
if (idx >= 3 && s[idx] == '?') {res = res * (idx - 2) % mod;
}
cout << (s[2] != '?' ? res : 0) << "\n";

由于设计到了取模,那么第一个 if 语句中的 res = res / (idx - 2); 在相除的时候不一定会整除,那么我们就不能使用除法了。这里我们变除法为乘法,使用乘法逆元,把 res = res / (idx - 2); 改为 res = res * qpow(idx - 2, mod - 2, mod) % mod;

C o d e Code Code

#include <bits/stdc++.h>
#define int long long
#define sz(a) ((int)a.size())
#define all(a) a.begin(), a.end()
using namespace std;
using PII = pair<int, int>;
using i128 = __int128;
const int N = 2e5 + 10;
const int mod = 998244353;int n, m;int qpow(int a, int b, int p) {int res = 1;while (b) {if (b & 1) {res = res * a % p;}a = a * a % p;b >>= 1;}return res;
}void solve() {cin >> n >> m;string s; cin >> s;s = "  " + s;int res = 1;for (int i = n; i >= 3; i --) {if (s[i] == '?') {res = res * (i - 2) % mod;}}cout << (s[2] != '?' ? res : 0) << "\n";while (m --) {int idx; cin >> idx; idx ++;string cc; cin >> cc;if (idx >= 3 && s[idx] == '?') {res = res * qpow(idx - 2, mod - 2, mod) % mod;}s[idx] = cc[0];if (idx >= 3 && s[idx] == '?') {res = res * (idx - 2) % mod;}cout << (s[2] != '?' ? res : 0) << "\n";}
}signed main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int T = 1;
//	cin >> T; cin.get();while (T --) solve();return 0;
}

http://www.ppmy.cn/news/1149929.html

相关文章

Leetcode.2867 统计树中的合法路径数目

题目链接 Leetcode.2867 统计树中的合法路径数目 rating : 2428 题目描述 给你一棵 n n n 个节点的无向树&#xff0c;节点编号为 1 1 1 到 n n n 。给你一个整数 n n n 和一个长度为 n − 1 n - 1 n−1 的二维整数数组 e d g e s edges edges &#xff0c;其中 e d g …

同创永益成为英迈首家签约生态伙伴

日前&#xff0c;同创永益已和英迈签署生态运营战略协议&#xff0c;并正式成为英迈全新打造的GTM生态圈的首位签约合作伙伴。双方将携手对“同创数字韧性平台”产品进行一站式联合解决方案的持续整合&#xff0c;并将大力推动该联合解决方案在市场上的进一步拓展。 云原生时代…

在服务器上解压.7z文件

1. 更新apt sudo apt-get update2. 安装p7zip sudo apt-get install p7zip-full3. 解压.7z文件 7za x WN18RR.7z

免费使用Salesforce Data Cloud!详细操作步骤来啦

Data Cloud是Salesforce向市场推出的增长最快的产品&#xff0c;这对Salesforce来说是一个重要竞争优势。 近期&#xff0c;Salesforce宣布客户可以免费使用Data Cloud。这就是所谓的零美元SKU&#xff0c;换句话说&#xff0c;这是一条不会产生任何成本的Salesforce产品线。 …

AI人工智能入门之图像识别

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是一门涵盖多个领域的科学技术&#xff0c;旨在使计算机能够模拟人类智能。 其中一个热门的应用领域就是图像识别。 图像识别是指计算机通过对一幅图像进行分析和处理&#xff0c;来识别和理解图像…

springboot中自定义过滤器用Component注解不用Configuration注解的坏处是什么

在Spring Boot中&#xff0c;如果你使用Component注解来标记自定义过滤器类而不使用Configuration注解&#xff0c;可能会有以下一些潜在的问题和限制&#xff1a; 过滤器顺序问题&#xff1a;使用Component注解标记的类是被自动扫描并创建为Bean的&#xff0c;它们的注册顺序…

Redis哨兵机制原理

Redis哨兵机制可以保证Redis服务的高可用性。它通过启动一个或多个哨兵进程&#xff0c;监控Redis主服务器是否宕机&#xff0c;如果宕机&#xff0c;哨兵进程会自动将一个从服务器&#xff08;Slave&#xff09;升级为主服务器&#xff08;Master&#xff09;&#xff0c;并通…

jmeter压测记录、使用方法

jmeter压测记录、使用方法 1、非gui方式执行压测命令2、压测命令输出解读 1、非gui方式执行压测命令 sh jmeter.sh -n -t test.jmx -l result.jtl2、压测命令输出解读 Active: 10 Started: 10 Finished: 0 Active: 10 正在进行的压测线程数&#xff1a;总的减去已完成的压测…