[ARC111F] Do you like query problems?

题意:

给出三个数 n,m,q

你有一个长度为 n 的序列 a,初始全为为 0,你有三种操作:
操作 1:给出 l,r,v,让区间 [l,r]vmin
操作 2:给出 l,r,v,让区间 [l,r]vmax
操作 3,给出 l,r,求区间和,将其累加进一个叫 sum 的变量里。

你并不需要维护这个数据结构,而是统计一共有 q 个操作的情况下,所有不同的操作序列中 3 操作得到的 sum 的总和,对 998244353 取模。你需要保证 v[0,m1]

分析:

img

显然的,输入的数据最多只可能有 ((2m+1)×n×(n+1)2)q 种。

对于这种问题,可以通过计算期望使得计算更简便。

不妨考虑计算每个位置对答案的贡献。

记一个 P(t,i) 表示经过 t修改操作最后变成 i 的概率。

考虑 dp 计算,如果要修改 i,能改变 i 的只会是 min(i,x)(x<i) 以及 max(i,x)(x>i)

易得:

P(t,i)=P(t1,i)×(n+1)+j=0(ji)mP(t1,j)2×m=12m+P(t1,i)2=1m1m×2t(i0)

然后再记一个 E(t) 表示一个数经过 t 次修改得期望值。

E(t)=i=1m1i×P(t,i)=(1m1m×2t)×m×(m1)2=(112t)m12

但不可能每次操作 [l,r] 都包含这个数吧(滑稽

因此需要记一个 zi 表示 i 被包含得概率。显然 z(i)=i×(ni+1)n×(n+1)2

于是我们就把 P(t,i) 升级到 w(t,i) 表示 i 经过 t 次全局操作得期望值:

w(t,i)=j=0tCtj×zij×(1zitj)E(t)=m12(1(1zi2)t)

Ti=1wi2

j 表示操作到 i 头上得次数,最后一步用了二项式定理推导。

再加入一波修改操作 g(t,i) 表示 i 经过 t 次操作(包含查询)的期望值:

g(t,i)=m12(1(2mTi+12m+1)t)

那么最后 x 的期望值为

E(x)=i=1nzi2m+1j=1qg(j1,i)=zi2m+1m12j=1q(1(2mTi+12m+1)j1)

显然可以用等比数列求和快速计算。

最后答案就是

E(x)×((2m+1)×n×(n+1)2)q

完结撒花!

img

代码:

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
int Pow(int a, int n) {
	if(n == 0) return 1;
	if(n == 1) return a % mod;
	int x = Pow(a, n / 2);
	if(n % 2 == 0) return x * x % mod;
	else return x * x % mod * a % mod;
}
int read() {
	char ch = getchar(); int x = 0, f = 1;
	while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); }
	while(ch >= '0' && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return x * f;
}
void write(int x) {
	if(x < 0) putchar('-'), x = -x;
	if(x > 9) write(x / 10);
	putchar('0' + x % 10);
}
int inv(int x) {
	return Pow(x, mod - 2);
}
int n, m, q, ans;
signed main() {
	cin >> n >> m >> q;
	for(int i = 1; i <= n; i++) {
		int p = i * (n - i + 1) % mod * inv((n + 1) * n / 2 % mod) % mod;
		int P = (1 - p * inv(2) % mod + mod) % mod;
		int z = (2 * m % mod * P % mod + 1) % mod * inv(2 * m + 1) % mod;
		int S = (Pow(z, q) - 1 + mod) % mod * inv(z - 1) % mod;	
		ans = (ans + p * inv(2 * m + 1) % mod * (m - 1) % mod * inv(2) % mod * ((q - S + mod) % mod) % mod) % mod;
	}
	cout << ans * Pow((2 * m + 1) % mod * n % mod * (n + 1) % mod * inv(2) % mod, q) % mod;
	return 0;
}
posted @   小超手123  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示