CF1886D. Monocarp and the Set 题解
建议标签:数学。
建议难度:普及/提高-。
思路
这个题目非常有意思。
当您苦思冥想都想不出来怎么正着做的时候,不妨把问题反过来想想。
题中说是加数,我们就可以把所有的操作反过来,从
首先如果是
其次如果是
当操作为
因为当第
对于每一个询问,如果要将是问号的一位改成别的(
还要特判,如果在只有两个数字的时候有
代码
/*******************************
| Author: SunnyYuan
| Problem: D. Monocarp and the Set
| Contest: Codeforces - Educational Codeforces Round 156 (Rated for Div. 2)
| URL: https://codeforces.com/contest/1886/problem/D
| When: 2023-10-11 14:41:49
|
| Memory: 256 MB
| Time: 2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
const int N = 300010, mod = 998244353;
int n, m, ans;
int modfs[N];
char s[N];
int pow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = 1ll * res * a % mod;
a = 1ll * a * a % mod;
b >>= 1;
}
return res;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> (s + 2);
for (int i = 1; i <= n; i++) modfs[i] = pow(i, mod - 2);
ans = 1;
for (int i = 3; i <= n; i++)
if (s[i] == '?')
ans = 1ll * ans * (i - 2) % mod;
if (s[2] == '?') cout << "0\n";
else cout << ans << '\n';
int p;
char x;
while (m--) {
cin >> p >> x;
p++;
if (s[p] == '?' && p > 2) ans = 1ll * ans * modfs[p - 2] % mod;
if (x == '?' && p > 2) ans = 1ll * ans * (p - 2) % mod;
s[p] = x;
if (s[2] == '?') cout << "0\n";
else cout << ans << '\n';
}
return 0;
}