Educational Codeforces Round 181 (Rated for Div. 2) ABCD题解

A. Difficult Contest

题意:

重新规划s,使其没有FFT" 或 "NTT

思路:

倒着排即可

代码

void solve() {
	 string s;
	 cin >> s;
	 map<char, int> mp;
	 for (int i = 0; i < s.size (); ++i) {
	 	 mp[s[i]] ++;
	 }
	 for (int i = 25; i >= 0; --i) {
	 	 if (mp[(char)('A' + i)]) {
	 	 	 for (int j = 0; j < mp[char ('A' + i)]; ++j) cout << (char)('A' + i);
	 	 }
	 }
	 cout << "\n";
}

B. Left and Down

题意:

思路:

\(ans = [1, 2]\),分类讨论即可。

代码

void solve() {
	 ll a, b, k;
	 cin >> a >> b >> k;
	 ll q = __gcd (a, b);
	 if (k >= a / q && k >= b / q) {
	 	 cout << "1" << "\n";
	 }else{
	 	 cout << "2" << "\n";
	 }
}

C. Count Good Numbers

题意:

找出\([l,r]\)中不含2,3,5,7因子数字的个数。

思路:

容斥原理
\(|A \cup B \cup C| = |A| + |B| + |C| - |A \cap B| - |B \cap C| - |C \cap A| + |A \cap B \cap C|\)

代码

 
ll cal (ll a) {
	 ll temp = 0;
	 temp += a / 2;
	 temp += a / 3;
	 temp += a / 5;
	 temp += a / 7;
	 temp -= a / 6;
	 temp -= a / 10;
	 temp -= a / 14;
	 temp -= a / 15;
	 temp -= a / 21;
	 temp -= a / 35;
	 temp += a / 30;
	 temp += a / 42;
	 temp += a / 105;
	 temp += a / 70;
	 temp -= a / 210;
	 return a - temp;
}
 
void solve() {
	 ll a, b;
	 cin >> a >> b;
	 cout << cal (b) - cal (a - 1) << "\n";
}

D. Segments Covering

题意:

有一条长度为 \(m\) 的线段,被划分成从 1 到 \(m\) 编号的 \(m\) 个单元格。给出 \(n\) 个区间,第 \(i\) 个区间用四个数 \((l_i, r_i, p_i, q_i)\) 描述:覆盖范围是闭区间 \([l_i, r_i]\)以概率 \(\frac{p_i}{q_i}\) 独立地出现(否则就不出现)。问:每个单元格都被恰好一条出现的区间覆盖 的总概率是多少?结果按最简分数 \(\frac{x}{y}\) 输出 \(x \cdot y^{-1} \mod 998244353\)

思路:

考虑dp

状态设计

\[dp[r]=Pr(前 r 个格子都已合法覆盖的概率) \]

转移方程
枚举每个右端点 \(r = 1..m\),再枚举所有以 \(r\) 结尾的区间 \((l, r)\):

  1. 左侧已合法的概率: \(\text{dp}[l-1]\)
  2. 区间自身出现的概率: \(p_i^*\)
  3. 区间段 \((l, r]\) 内其他右端点 \(\leq r\) 的区间全部不出现:

    \[\frac{\text{pref}[r]}{\text{pref}[l-1]} \]

  4. 上一步里把当前区间自己的 \(w_i\) 也乘进去了,需要除回去,并与第 2 步合并成

    \[\frac{p_i^*}{1 - p_i^*} \]

于是贡献为

\[\text{dp}[l-1] \times \frac{p_i^*}{1 - p_i^*} \times \frac{\text{pref}[r]}{\text{pref}[l-1]} \]

把所有区间的贡献累加得到 \(\text{dp}[r]\)

代码

#include<bits/stdc++.h>
#define ll long long
#define ce cerr
#define ull unsigned long long
#define lll __int128
using namespace std;

const int inf = 0x3f3f3f3f;
const ll iinf = 1e18;
const int mod = 998244353;

//cin.ignore(std::numeric_limits< streamsize >::max(), '\n');
int t;

ll ksm (ll a, ll b) {
	 ll temp = 1;
	 while (b) {
	 	 if (b & 1) temp = temp * a % mod;
	 	 b >>= 1;
	 	 a = a * a % mod;
	 }
	 return temp;
}
struct node {
	 ll l, r, p;
};

bool cmp (node a, node b) {
	 return a.l < b.l;
}
void solve() {
	 ll n, m;
	 cin >> n >> m;
	 vector<ll> dp (m + 1, 0);
	 dp[0] = 1;
	 vector<ll> mul (m + 1);
	 vector<node> nd (n + 1);
	 for (int i = 0; i <= m; ++i) mul[i] = 1;
	 for (int i = 1; i <= n; ++i) {
	 	 ll l, r, p, q;
	 	 cin >> l >> r >> p >> q;
	 	 ll pp = ksm (q, mod - 2) * p % mod;
	 	 nd[i].l = l;
	 	 nd[i].r = r;
	 	 nd[i].p = pp;
	 	 ll temp = (1 - pp + mod) % mod;
	 	 mul[r] = mul[r] * temp % mod; 
	 }
	 for (int i = 1; i <= m; ++i) {
	 	 mul[i] = mul[i - 1] * mul[i] % mod;
	 }
	 sort (nd.begin () + 1, nd.end (), cmp);
	 for (int i = 1; i <= n; ++i) {
	 	 ll temp = dp[nd[i].l - 1] * nd[i].p % mod * mul[nd[i].r] % mod * ksm (mul[nd[i].l - 1], mod - 2) % mod * ksm ((1 - nd[i].p + mod) % mod, mod - 2) % mod;
	 	 dp[nd[i].r] = (dp[nd[i].r] + temp) % mod;
	 }
	 cout << dp[m] << "\n";
}
int main() {
	 ios::sync_with_stdio (false);
	 cin.tie(NULL);
	 cout.tie(NULL);
	 t = 1;
	 // cin >> t;
	 while (t --) {
	 	 solve();
	 }
	 return 0;
}
posted @ 2025-07-26 02:32  Li_Yujia  阅读(58)  评论(0)    收藏  举报