QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#578339 | #9330. Series Sum | Afterlife# | RE | 1901ms | 85680kb | C++20 | 5.2kb | 2024-09-20 18:22:13 | 2024-09-20 18:22:17 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#define int long long
using ll=long long;
using poly=vector<int>;
const int N=2e6+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() ;
}
详细
Test #1:
score: 100
Accepted
time: 4ms
memory: 30080kb
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: 6ms
memory: 30028kb
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: 621ms
memory: 30780kb
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: 1901ms
memory: 85680kb
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
Runtime Error
input:
4 62 12597 13 15082 2 11295 1 330