QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#578358#9330. Series SumAfterlifeTL 1864ms84756kbC++205.4kb2024-09-20 18:35:592024-09-20 18:36:01

Judging History

你现在查看的是最新测评结果

  • [2024-09-20 18:36:01]
  • 评测
  • 测评结果:TL
  • 用时:1864ms
  • 内存:84756kb
  • [2024-09-20 18:35:59]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;

#define int long long

using ll=long long;

using poly=vector<int>;

const int N=4e6+1e3+7,P=998244353,mod=P;

int qpow(int a,int b)
{
    int ret=1;
    while(b)
    {
        if(b&1)
            ret=ret*a%P;
        b>>=1;
        a=a*a%P;
    }
    return ret;
}

namespace Core {
    int a[N],b[N],w[N],rev[N];

    void NTT(int *a,int len)
    {
        for(int i=1;i<len;i++)
            if(i>rev[i])
                swap(a[i],a[rev[i]]);
        for(int d=1;d<len;d<<=1)
            for(int m=d<<1,i=0;i<len;i+=m)
                for(int j=0;j<d;j++)
                {
                    int x=a[i+j],y=a[i+j+d]*w[len/m*j]%P;
                    a[i+j]=(x+y>=P?x+y-P:x+y);
                    a[i+j+d]=(x-y<0?x-y+P:x-y);
                }
    }
}

int lastlen=-1;

poly operator *(const poly &va,const poly &vb)
{
    using namespace Core;
    int len=1;
    while(len<(int)va.size()+(int)vb.size()-1)
        len<<=1;
    for(int i=0;i<len;i++)
        a[i]=(i<(int)va.size()?va[i]:0);
    for(int i=0;i<len;i++)
        b[i]=(i<(int)vb.size()?vb[i]:0);
    if(lastlen!=len)
    {
        for(int i=1;i<len;i++)
            rev[i]=rev[i>>1]>>1|(i&1?len>>1:0);
        w[0]=1;
        w[1]=qpow(3,(P-1)/len);
        for(int i=2;i<len;i++)
            w[i]=1ll*w[i-1]*w[1]%P;
        lastlen=len;
    }
    NTT(a,len);
    NTT(b,len);
    for(int i=0;i<len;i++)
        a[i]=1ll*a[i]*b[i]%P;
    reverse(a+1,a+len);
    NTT(a,len);
    poly c(va.size()+vb.size()-1);
    for(int i=0,invlen=qpow(len,P-2);i<(int)c.size();i++)
        c[i]=a[i]*invlen%P;
    return c;
}

poly Fix(poly a,int n)
{
    a.resize(n);
    return a;
}

poly Inv(poly f,int n)
{
    poly g(1,qpow(f[0],P-2));
    while((int)g.size()<n)
    {
        int nlen=min<int>(g.size()<<1,n);
        poly tmp(Fix(Fix(f,nlen)*g,nlen));
        for(int i=0;i<nlen;i++)
            tmp[i]=(P-tmp[i]+(i==0?2:0))%P;
        g=Fix(g*tmp,nlen);
    }
    return g;
}

int k , p;
int t[N] , rt[N];

poly calc(int k,int p) {
    poly f(2) ; f[1] = 1;
    int ck = 1;
    for(int d = (int)__lg(k) - 1 ; d >= 0 ; d--) {
        ///
        poly g(f.size()) ;
        int l = g.size() - 1;
        int z = mod - ck;
        for(int i = 0, j = 1;i < g.size();i++, j = j * z % mod) g[l - i] = 1LL * rt[i] * j % mod;
        poly c = f * g;
        for(int i = 0;i <= ck ; i++) {
            c[i] = 1LL * c[i + l] * rt[i] % mod;
            f[i] = 1LL * f[i] * rt[i] % mod;
        }
        c.resize(ck + 1);
        f = f * c;

        ck *= 2;
        // for(int i = 0;i < f.size();i++) printf("%d ",f[i]) ; printf("\n");
        if((k >> d) & 1) {
            /// * (x - ck)
            f.push_back(0);
            for(int i = f.size() - 1;i >= 0;i--) {
                if(i) f[i] = (1LL * f[i] * (mod - ck) + f[i - 1]) % mod;
                else f[i] = 1LL * f[i] * (mod - ck) % mod;
            }
            ck++ ;
        }
        if(d) {
            for(int i = 0;i <= ck;i++) f[i] = 1LL * f[i] * t[i] % mod;
        }
    }
    // for(int i = 0;i < f.size();i++) printf("%d ",f[i]) ; printf("\n");

    // exit(0) ;
    poly ans(1) ; ans[0] = 1;
    bool ff = 0;
    while(p) {
        if(p & 1) {
            if(ff) ans = ans * f;
            else ans = f;
            ff = 1;

        }
        p >>= 1;
        if(p) f = f * f;
    }
    return ans;
}
int C(int a,int b) {
    return 1LL * t[a] * rt[b] %mod * rt[a - b] % mod;
}
void solv() {
    cin >> k >> p;
    poly p2 = calc(k , p);
    // for(int i = 0;i < p2.size();i++) printf("%d ",p2[i]) ;
    // printf("\n");
    int d = qpow(qpow(t[k] , mod - 2) , p) ;
    for(int i = 0;i < p2.size();i++) p2[i] = 1LL * p2[i] * d % mod;

    // poly F(k * p + 1) ;
    // F[0] = 1;
    // for(int i = 1;i <= k*p;i++) {
    //     for(int j = 0;j < i;j++) {
    //         int sol = 2LL * F[j] * C(i,j) % mod;
    //         if((i - j + 1) & 1) F[i] = (F[i] - sol + mod) % mod;
    //         else F[i] = (F[i] + sol) % mod;
    //     }
    // }
    // for(int i = 0;i <= k*p;i++) {
    //     F[i] = 1LL * F[i] * rt[i] % mod;
    //     printf("%d ",F[i]) ;
    // }
    // printf("\n") ;
    // exit(0) ;
    poly T(k * p + 1);
    T[0] = 0;
    for(int i = 1;i <= k*p;i++) {
        T[i] = rt[i] ;
        if((i + 1) & 1) T[i] = (mod - T[i]) % mod;
    }

    for(int i = 0;i <= k*p;i++) {
        T[i] = (2*T[i]) % mod ;
    }
    T[0] = (T[0] - 1 + mod) % mod;
    // poly K = F * T;
    // for(int i = 0;i <= k*p;i++) {
    //     printf("%d ",K[i] % mod) ; 
    // }
    // printf("\n");

    poly f = Inv(T , k*p + 1) ;
    // poly c = Fix(f * T, k * p  + 1);
    // for(int i = 0;i < c.size();i++) printf("%d ",c[i]) ; printf("\n");

    for(int i = 0;i < f.size();i++) {
        f[i] = 1LL * f[i] * (mod - 1) % mod;
        f[i] = 1LL * f[i] * t[i] % mod;
        // printf("%d ",f[i]);
    }
    // printf("\n");

    int ans = 0;
    for(int i = 0;i <= k * p;i++) {
        ans = (ans + 1LL * f[i] * p2[i]) % mod;
    }
    cout << ans << '\n';
}
signed main()
{
    ios::sync_with_stdio(false) ; cin.tie(0) ;
    int T;cin >> T;
    int N = 1e6;
    t[0] = rt[0] = 1;
    for(int i = 1 ; i <= N;i++) t[i] = 1LL * t[i - 1] * i % mod;
    rt[N] = qpow(t[N] , mod - 2);
    for(int i = N - 1;i >= 0;i--) rt[i] = 1LL * rt[i + 1] * (i + 1) % mod;

    while(T--) solv() ;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 31220kb

input:

3
2 3
1 10
9 6

output:

818
204495126
16726290

result:

ok 3 number(s): "818 204495126 16726290"

Test #2:

score: 0
Accepted
time: 9ms
memory: 31516kb

input:

3
10 1
1 3
1 2

output:

2
26
6

result:

ok 3 number(s): "2 26 6"

Test #3:

score: 0
Accepted
time: 583ms
memory: 30672kb

input:

2112
16 51
27 30
32 22
6 69
1 7
6 40
15 63
23 37
11 57
6 92
8 62
5 50
11 76
1 57
99 8
2 90
35 10
13 54
6 33
8 70
14 48
12 63
7 99
85 7
14 60
7 78
22 22
1 53
6 61
2 67
8 68
5 67
7 57
8 79
11 29
15 44
8 62
19 39
9 71
3 65
3 83
6 16
11 86
7 25
124 6
1 21
5 76
17 35
14 29
1 55
67 13
987 1
8 27
4 99
8 19...

output:

958728366
182850046
337462356
238321759
94586
688819126
880558546
673294800
592760052
772846256
555807947
834237048
258386591
443217990
83210442
741605708
687991731
380324156
884202426
190172937
130140451
931313604
659396498
344165836
434542961
111646504
6836992
571531367
631528990
880394933
1976309...

result:

ok 2112 numbers

Test #4:

score: 0
Accepted
time: 1864ms
memory: 84756kb

input:

6
1 164257
7 10955
1 30358
1 198674
1 206507
1 323519

output:

450748134
285759990
479497879
856048370
75480834
220335166

result:

ok 6 numbers

Test #5:

score: -100
Time Limit Exceeded

input:

4
62 12597
13 15082
2 11295
1 330

output:

134578883
817592796
66930551
383110659

result: