题目大意
给出 n n n,求 ∏ i = 1 n ∏ j = 1 i ∏ k = 1 j k k \prod \limits_{i=1}^{n} \prod\limits_{j=1}^{i} \prod \limits_{k=1}^{j} k^k i=1∏nj=1∏ik=1∏jkk 对 998244353 998244353 998244353 取模后的值。
思路讲解.
不知道快速幂的请移步 这里。
如果直接枚举
i
,
j
,
k
i,j,k
i,j,k,那时间复杂度为遍历的时长乘上快速幂的时长,即
O
(
n
3
l
o
g
n
)
O(n^3logn)
O(n3logn),肯定会 TLE
。
仔细观察,不难发现。在遍历时,要使 k k k^k kk 出现, j j j 必须不小于 k k k,否则遍历不到 k k k。所以 j j j 有 n − k + 1 n-k+1 n−k+1 种选择, i i i 有 n − j + 1 n-j+1 n−j+1 种选择,所以 k k k^k kk 的出现次数为 ∑ j = k n ∑ i = j n 1 \sum^{n}_ {j=k}\sum^{n}_ {i=j} 1 ∑j=kn∑i=jn1,用等差数列公式求和,为 ( 2 + n − k ) × ( n − k + 1 ) 2 \frac{(2+n-k) \times (n-k+1)}{2} 2(2+n−k)×(n−k+1)。所以 k k k^k kk 在 ∏ i = 1 n ∏ j = 1 i ∏ k = 1 j k k \prod \limits_{i=1}^{n} \prod\limits_{j=1}^{i} \prod \limits_{k=1}^{j} k^k i=1∏nj=1∏ik=1∏jkk 中出现的次数为 ( 2 + n − k ) × ( 1 + n − k ) 2 \frac{(2+n-k) \times (1+n-k)}{2} 2(2+n−k)×(1+n−k)。
所以我们只需遍历 k k k,用快速幂求一下 ( k k ) ( 2 + n − k ) × ( 1 + n − k ) 2 (k^k)^\frac{(2+n-k) \times (1+n-k)}{2} (kk)2(2+n−k)×(1+n−k),即 k k × ( 2 + n − k ) × ( 1 + n − k ) 2 k^{k \times \frac{(2+n-k) \times (1+n-k)}{2}} kk×2(2+n−k)×(1+n−k) 的值即可。算法复杂度为 O ( n log n ) O(n \log{n}) O(nlogn)。
代码实现
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
long long quick_mi(int a,long long b){
long long sum=1,base=a;
while(b){
if(b&1)
sum*=base,sum%=mod;
b>>=1,base*=base,base%=mod;
}
return sum;
}
int main(){
int n;
long long ans=1;
cin>>n;
for(int k=1;k<=n;k++){
long long t=1LL*(2+n-k)*(1+n-k)/2;
ans*=quick_mi(k,1LL*k*t),ans%=mod;
//cout<<t<<' '<<ans<<'\n';
}
printf("%lld",ans);
return 0;
}
完结撒花!