《牛客练习赛52A》

对于第一个式子。

分析内层循环可以发现,可以优化为i*n的前缀和。那么可以O(n)求出。

那么即为$sum_{i = 1}^{n} i *pre[n]$

再仔细观察我们可以提出pre[n]。那么就变成了pre[n]*pre[n]。至此就可以O(1)求出了。

pre[n]不需要预处理,因为这里空间卡得紧,只需要n*(n+1)/2来算出即可。

对于第二个式子。

分析内存循环发现,可以优化为n!*i^n。

那么我们可以预处理出阶乘,然后递推i,对于每个i快速幂求i^n。

即为$coprod_{i= 1}^{n} i^n * n!$

复杂度为nlogn,但是n最大为1e7,还是会T。

我们对i也拆开,进行分析之后,可以发现$coprod_{i= 1}^{n} i^n$

其实就是n!^n,然后每次都要*n!。那么$ans = n!^{2*n}$

那么,就可以logn求出了。

// Author: levil
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e7+5;
const int M = 12005;
const LL Mod = 998244353;
#define rg register
#define pi acos(-1)
#define INF 1e5+1
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
    void print(int x){
        if(x < 0){x = -x;putchar('-');}
        if(x > 9) print(x/10);
        putchar(x%10+'0');
    }
}
using namespace FASTIO;
void FRE(){
/*freopen("data1.in","r",stdin);
freopen("data1.out","w",stdout);*/}

LL f[N];
void init()
{
    f[0] = 1;
    for(rg int i = 1;i < N;++i) 
    {
        f[i] = f[i-1]*i%Mod;
    }
}
LL quick_mi(LL a,LL b)
{
    LL re = 1;
    while(b)
    {
        if(b&1) re = re*a%Mod;
        a = a*a%Mod;
        b >>= 1;
    }
    return re;
}
int main()
{
    init();
    int ca;ca = read();
    while(ca--)
    {
        int n;n = read();
        LL ans1 = 0,pre;
        if(n%2 == 0) pre = 1LL*n/2*(n+1)%Mod;
        else pre = 1LL*(n+1)/2*n%Mod;
        ans1 = pre*pre%Mod;
        LL ans2 = quick_mi(f[n],2LL*n);
        printf("%lld %lld
",ans1,ans2);
    }
    system("pause");
}
View Code
原文地址:https://www.cnblogs.com/zwjzwj/p/13580747.html