2020 ICPC Macau A. Accelerator(期望,计数,分治FFT)(每日一题 21.7.6)

Posted 繁凡さん

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020 ICPC Macau A. Accelerator(期望,计数,分治FFT)(每日一题 21.7.6)相关的知识,希望对你有一定的参考价值。

整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


2020 ICPC Macau A. Accelerator(分治FFT)

Problem

给定长度为 n n n 的数组 a i a_i ai ,对于 1 ∼ n 1\\sim n 1n 的所有的排列 p i p_i pi ,计算 ( ( ( ( 0 + 1 ) ∗ a p 1 + 1 ) ∗ a p 2 + ⋯   ) + 1 ) ∗ a p n ((((0 + 1) *a_{p_1} + 1) * a_{p_2} + \\cdots) + 1) * a_{p_n} ((((0+1)ap1+1)ap2+)+1)apn 的期望。

n ≤ 1 0 5 n\\le 10^5 n105

Solution

显然我们把要求的式子展开以后有:

v a l = ∏ i = 1 n a p i + ∏ i = 2 n a p i + ⋯ + ∏ i = n n a p i val = \\prod\\limits_{i = 1}^{n}a_{p_i} + \\prod\\limits_{i = 2}^{n}a_{p_i} + \\cdots + \\prod\\limits_{i = n}^{n}a_{p_i} val=i=1napi+i=2napi++i=nnapi

考虑对于任意一个排列的乘积, ∏ i n a p i \\displaystyle\\prod\\limits_{i}^{n}a_{p_i} inapi ,它自己对于答案期望的贡献。

显然期望等于权值乘以概率,对于一段长度为 i i i 的排列,它的概率显然为 i ! × ( n − i ) ! n ! \\cfrac{i!\\times (n-i)!}{n!} n!i!×(ni)!,那么它对答案的贡献显然为 ∏ i n a p i × i ! × ( n − i ) ! n ! \\displaystyle\\prod\\limits_{i}^{n}a_{p_i}\\times \\cfrac{i!\\times (n-i)!}{n!} inapi×n!i!×(ni)!

由于期望的可加性,我们发现对于所有的长度为 i i i 的排列,它的贡献均为 ∏ i n a p i × i ! × ( n − i ) ! n ! \\displaystyle\\prod\\limits_{i}^{n}a_{p_i}\\times \\cfrac{i!\\times (n-i)!}{n!} inapi×n!i!×(ni)!,所以我们可以设 f i f_i fi 表示从 n n n 个数中取 i i i 个数的乘积和 f ( i ) = ∑ p ∈ S ∏ i n a p i f(i)=\\displaystyle\\sum_{p\\in S}\\prod\\limits_{i}^{n}a_{p_i} f(i)=pSinapi S S S 为从 n n n 个数中取 i i i 个数的集合。

显然要求的答案期望 E ( x ) E(x) E(x)

E ( x ) = ∑ i = 1 n f i × i ! × ( n − i ) ! n ! \\begin{aligned} E(x)= \\cfrac{\\sum\\limits_{i = 1} ^ {n} f_i\\times i! \\times (n - i) !}{n!} \\end{aligned} E(x)=ni=1nfi×i!×(ni)!

也就是我们只需要求出 1 ∼ n 1\\sim n 1n f i f_i fi 即可。

显然有:

f i = ∑ j = 1 i f i − j × f j f_i=\\sum_{j=1}^{i}f_{i-j}\\times f_j fi=j=1ifij×fj

f 1 = a i f_1=a_i f1=ai

发现这显然就是一个自己卷自己的分治FFT的模板,直接用分治FFT O ( n log ⁡ 2 n ) O(n\\log^2 n) O(nlog2n) 计算即可。

Hint

CF GNU C++17 (64) = 327 ms,GNU C++17 = 951 ms ∼ \\sim TLE …

Code

#include <bits/stdc++.h> 
using namespace std; 
using ll = long long;
const int N = 2e5 + 5, mod = 998244353, P = 998244353, MOD = 998244353;

template <typename T> inline void read(T& t) {
    int f = 0, c = getchar(); t = 0; 
    while (!isdigit(c)) f |= c == '-', c = getchar();
    while (isdigit(c)) t = t * 10以上是关于2020 ICPC Macau A. Accelerator(期望,计数,分治FFT)(每日一题 21.7.6)的主要内容,如果未能解决你的问题,请参考以下文章

The 2020 ICPC Asia Macau Regional Contest B Boring Problem

ACM-ICPC 2017 Asia Urumqi A. Coins

2018 ICPC Asia Singapore Regional A. Largest Triangle (计算几何)

ACM-ICPC 2018 徐州赛区网络预赛 A. Hard to prepare

ACM-ICPC 2017 Asia Urumqi:A. Coins(DP) 组合数学

ACM-ICPC 2018 徐州赛区网络预赛 A. Hard to prepare (组合数学,递归)