RiverSheepSHEEP

[ARC154E] Reverse and Inversion

奔跑的心634·2023-03-15 21:52·23 次阅读

[ARC154E] Reverse and Inversion

[ARC154E] Reverse and Inversion#

先化简f(P),考虑每一个 i 的贡献,它等于

ii(j<i[Pj>Pi]j>i[Pj<Pi])

因为j<i[Pj>Pi]=i1(Pi1j>i[Pj<Pi]))
所以原式为

ii2iiPi

现在的关键就是求出iPi,因为对于每一种方案的值都要求出,相当于求出其期望值。
考虑 i 期望被交换到哪个位置,假设 一次操作后 i 被交换到 j,其概率为 2min(i,j,ni+1,nj+1)n(n+1),观察发现 i 交换到 nj+1 的概率和其是一样的,所以如果 i 被操作过,其期望位置为 n+12,否则为位置为 i
易得位置 i 没被操作的概率为 pi=(12i(ni+1)n(n+1))m,那么 iPi 的期望值为 Pi(pii+(1pi)n+12)

Code
Copy
#include<cstdio> #include<iostream> #define IN inline #define LL long long using namespace std; const int N = 2e5 + 5, P = 998244353; LL a[N], p[N], n, m; IN int read() { int t = 0,res = 0; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) t |= (ch == '-'); for (; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ 48); return t ? -res : res; } LL fpow(LL x, LL y) { LL res = 1; y = y % P; for (; x; x >>= 1, y = y * y % P) if (x & 1) res = res * y % P; return res; } int main() { n = read(), m = read(); for (int i = 1; i <= n; i++) a[i] = read(); LL inv = fpow(P - 2, n * (n + 1) / 2), iv2 = fpow(P - 2, 2LL); for (LL i = 1; i <= n; i++) p[i] = fpow(m, (P + 1 - (LL)i * (n - i + 1) % P * inv % P) % P); LL ans = 0; for (LL i = 1; i <= n; i++) (ans += P + i * i % P - a[i] * (p[i] * i % P + (1 + P - p[i]) * (n + 1) % P * iv2 % P) % P) %= P; printf("%lld\n", ans * fpow(m, n * (n + 1) / 2) % P); }
posted @   RiverSheep  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
目录
点击右上角即可分享
微信分享提示