QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#578340#9330. Series SumAfterlife#TL 1920ms85016kbC++205.2kb2024-09-20 18:22:512024-09-20 18:22:52

Judging History

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

  • [2024-09-20 18:22:52]
  • 评测
  • 测评结果:TL
  • 用时:1920ms
  • 内存:85016kb
  • [2024-09-20 18:22:51]
  • 提交

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);
                }
    }
}

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);
    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;
    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;
        for(int i = 0;i < g.size();i++) g[l - i] = 1LL * rt[i] * qpow((mod - ck) % mod , i) % 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");


    poly ans(1) ; ans[0] = 1;
    while(p) {
        if(p & 1) ans = ans * f;
        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") ;

    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: 13ms
memory: 31348kb

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: 12ms
memory: 30192kb

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: 625ms
memory: 31696kb

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: 1920ms
memory: 85016kb

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:


result: