题解:P11029 『DABOI Round 1』A Simple Problem

题目传送门

题目大意

给出 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=1nj=1ik=1jkk 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 nk+1 种选择, i i i n − j + 1 n-j+1 nj+1 种选择,所以 k k k^k kk 的出现次数为 ∑ j = k n ∑ i = j n 1 \sum^{n}_ {j=k}\sum^{n}_ {i=j} 1 j=kni=jn1,用等差数列公式求和,为 ( 2 + n − k ) × ( n − k + 1 ) 2 \frac{(2+n-k) \times (n-k+1)}{2} 2(2+nk)×(nk+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=1nj=1ik=1jkk 中出现的次数为 ( 2 + n − k ) × ( 1 + n − k ) 2 \frac{(2+n-k) \times (1+n-k)}{2} 2(2+nk)×(1+nk)

所以我们只需遍历 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+nk)×(1+nk),即 k k × ( 2 + n − k ) × ( 1 + n − k ) 2 k^{k \times \frac{(2+n-k) \times (1+n-k)}{2}} kk×2(2+nk)×(1+nk) 的值即可。算法复杂度为 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;
}

完结撒花!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值