题目传送门
接着翻译:
题目描述 Description
我们都知道,六花同学数学不好,勇太君担心这个状况,所以他给了六花酱一些数学问题作为练习,这里有其中的一道题:
勇太君有 n n n个数字 A [ 1 ] A[1] A[1]~ A [ n ] A[n] A[n],还有一个数字 K K K。对于任意一个 A A A的非空子集 S S S, S S S的价值等于 S S S集合中最大的 min ( ∣ S ∣ , K ) \min(|S|,K) min(∣S∣,K)个数之和(译者注: ∣ S ∣ |S| ∣S∣表示集合 S S S的大小),数组 A A A的价值为所有 A A A的非空子集的价值和。
现在勇太君给出了这 n n n个数,他想知道对任意 K K K属于 [ 1 , n ] [1,n] [1,n]的数组的价值。
这对于Rikka童鞋太难了。你能帮助她吗?
输入 Input
第一行包含一个数字 t ( 1 ≤ t ≤ 10 ) t(1\le t\le 10) t(1≤t≤10),表示数据组数。
对于每组数据,第一行有一个整数 n ( 1 ≤ n ≤ 1 0 5 ) n(1\le n\le 10^5) n(1≤n≤105),表示勇太君有的数字。第二行包含 n n n个数 A [ 1 ] A[1] A[1]~ A [ n ] ( 0 ≤ A [ i ] ≤ 1 0 9 ) A[n](0\le A[i]\le 10^9) A[n](0≤A[i]≤109)。
输出 Output
对于每组数据,输出一行包含 n n n个整数,第 i i i个数是当 K = i K=i K=i时的数组价值。这个答案会非常大,所以你只需输出答案对 998244353 998244353 998244353取模的结果。
PoPoQQQ:“对于模一个数的计数问题只能用NTT。”
推一下公式。因为是前
min
(
∣
S
∣
,
K
)
\min(|S|,K)
min(∣S∣,K)大,所以集合中没有
K
K
K个数的话其余补
0
0
0即可。
先将
A
[
i
]
A[i]
A[i]从大到小排序,我们就可以分开计算一个数
A
[
i
]
A[i]
A[i]的贡献了,这里的贡献指对所有集合的贡献。
因为
A
[
i
]
A[i]
A[i]需要作为集合中第
k
k
k大出现,所以这个集合至少有
k
−
1
k-1
k−1个数,比
A
[
i
]
A[i]
A[i]大的选择
k
−
1
k-1
k−1个进入集合,剩下比
A
[
i
]
A[i]
A[i]小的可选可不选,这样就是
2
n
−
i
2^{n-i}
2n−i种选择。总结起来,用
f
[
k
]
f[k]
f[k]表示所有数作为集合第
k
k
k大的总贡献。
f
[
k
]
f[k]
f[k]可表示为:
f
[
k
]
=
∑
i
=
k
n
(
i
−
1
k
−
1
)
2
n
−
i
A
[
i
]
f[k]=\sum\limits_{i=k}^n\binom{i-1}{k-1}2^{n-i}A[i]
f[k]=i=k∑n(k−1i−1)2n−iA[i]
嗯这么算是
O
(
n
2
)
O(n^2)
O(n2)的接着超时……
于是我们对这个式子变下形:
f
[
k
]
=
∑
i
=
k
n
(
i
−
1
)
!
(
k
−
1
)
!
(
i
−
k
)
!
2
n
−
i
A
[
i
]
=
1
(
k
−
1
)
!
∑
i
=
k
n
(
i
−
1
)
!
(
i
−
k
)
!
2
n
−
i
A
[
i
]
=
1
(
k
−
1
)
!
∑
i
=
0
n
−
k
(
(
i
+
k
)
−
1
)
!
(
(
i
+
k
)
−
k
)
!
2
n
−
(
i
+
k
)
A
[
i
+
k
]
=
1
2
k
(
k
−
1
)
!
∑
i
=
0
n
−
k
2
n
−
i
i
!
(
i
+
k
−
1
)
!
A
[
i
+
k
]
\begin{aligned} f[k]&=\sum\limits_{i=k}^n\frac{(i-1)!}{(k-1)!(i-k)!}2^{n-i}A[i]\\ &=\frac{1}{(k-1)!}\sum\limits_{i=k}^n\frac{(i-1)!}{(i-k)!}2^{n-i}A[i]\\ &=\frac{1}{(k-1)!}\sum\limits_{i=0}^{n-k}\frac{((i+k)-1)!}{((i+k)-k)!}2^{n-(i+k)}A[i+k]\\ &=\frac{1}{2^k(k-1)!}\sum\limits_{i=0}^{n-k}\frac{2^{n-i}}{i!}(i+k-1)!A[i+k] \end{aligned}
f[k]=i=k∑n(k−1)!(i−k)!(i−1)!2n−iA[i]=(k−1)!1i=k∑n(i−k)!(i−1)!2n−iA[i]=(k−1)!1i=0∑n−k((i+k)−k)!((i+k)−1)!2n−(i+k)A[i+k]=2k(k−1)!1i=0∑n−ki!2n−i(i+k−1)!A[i+k]
诶诶诶
(
i
+
k
−
1
)
!
(i+k-1)!
(i+k−1)!和
A
[
i
+
k
]
A[i+k]
A[i+k]咋这么一样呢……
诶诶诶
n
−
i
+
i
+
k
=
n
+
k
n-i+i+k=n+k
n−i+i+k=n+k咋是定值呢……
然后就是卷积的套路了……设
a
[
i
]
=
2
n
−
i
i
!
a[i]=\frac{2^{n-i}}{i!}
a[i]=i!2n−i,
b
[
i
]
=
(
i
−
1
)
!
A
[
i
]
b[i]=(i-1)!A[i]
b[i]=(i−1)!A[i],先把
b
b
b翻转过来,然后就是卷积了……只不过这次是用NTT完成计算,最后的答案
f
[
k
]
=
a
[
n
−
k
]
f[k]=a[n-k]
f[k]=a[n−k],还应该把系数乘上再求个前缀和。
时间复杂度
O
(
t
n
log
2
n
)
O(tn\log_2n)
O(tnlog2n)
Code