在 nttexp 函数里面:
while (limit<n*2) {
limit*=2;
}
这个能A,但是这个就连样例都没过:
while (limit<=n*2) {
limit*=2;
}
完整代码是:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cstdlib>
using namespace std;
#define ll long long
const int MAXN = 4e5, g = 3, invg = 332748118, mod = 998244353;
int n, limit, invlimit, R[MAXN+5];
ll a[MAXN+5], b[MAXN+5], tempinv[MAXN+5], templn[MAXN+5], tempexp[MAXN+5];
ll qpow(ll x, ll y) {
if (y==0) return 1;
ll mid = qpow(x, y/2);
if (y%2) return mid*mid%mod*x%mod;
else return mid*mid%mod;
}
void ntt(int limit, ll a[], int dir) {
for (int p=0;p<limit;p++) {
if (p<R[p]) swap(a[p], a[R[p]]);
}
for (int p=2;p<=limit;p*=2) {
ll g1 = qpow(dir==1?g:invg, (mod-1)/p);
for (int k=0;k<limit;k+=p) {
ll gi = 1;
for (int i=k;i<k+p/2;i++) {
ll x = a[i], y = gi*a[i+p/2]%mod;
a[i] = (x+y)%mod;
a[i+p/2] = (x-y+mod)%mod;
gi*=g1;
gi%=mod;
}
}
}
if (dir==-1) {
for (int p=0;p<limit;p++) {
a[p]*=invlimit;
a[p]%=mod;
}
}
return ;
}
void nttinv(int n, ll b[], ll a[]) {
if (n==1) {
b[0] = qpow(a[0], mod-2);
for (int p=1;p<=MAXN;p++) {
b[p] = 0;
}
return ;
}
nttinv((n+1)/2, b, a);
limit = 1;
while (limit<=2*n) {
limit*=2;
}
invlimit = qpow(limit, mod-2);
for (int p=0;p<limit;p++) {
R[p] = R[p/2]/2+((p&1)?limit/2:0);
}
for (int p=0;p<n;p++) {
tempinv[p] = a[p];
}
for (int p=n;p<limit;p++) {
tempinv[p] = 0;
b[p] = 0;
}
ntt(limit, tempinv, 1);
ntt(limit, b, 1);
for (int p=0;p<limit;p++) {
b[p] = (2*b[p]%mod-tempinv[p]*b[p]%mod*b[p]%mod+mod)%mod;
}
ntt(limit, b, -1);
for (int p=n;p<limit;p++) {
b[p] = 0;
}
return ;
}
void nttln(int n, ll a[]) {
nttinv(n, templn, a);
limit = 1;
while (limit<=2*n) {
limit*=2;
}
invlimit = qpow(limit, mod-2);
for (int p=0;p<limit;p++) {
R[p] = R[p/2]/2+((p&1)?limit/2:0);
}
for (int p=0;p<n-1;p++) {
a[p] = a[p+1]*(p+1)%mod;
}
a[n-1] = 0;
ntt(limit, a, 1);
ntt(limit, templn, 1);
for (int p=0;p<limit;p++) {
a[p] = a[p]*templn[p]%mod;
}
ntt(limit, a, -1);
for (int p=n-1;p>=1;p--) {
a[p] = a[p-1]*qpow(p, mod-2)%mod;
}
a[0] = 0;
for (int p=n;p<limit;p++) {
a[p] = 0;
}
return ;
}
void nttexp(int n, ll b[], ll a[]) {
if (n==1) {
b[0] = 1;
for (int p=1;p<MAXN;p++) {
b[p] = 0;
}
return ;
}
nttexp((n+1)/2, b, a);
for (int p=0;p<n;p++) {
tempexp[p] = b[p];
}
nttln(n, tempexp);
limit = 1;
while (limit<n*2) {
limit*=2;
}
invlimit = qpow(limit, mod-2);
for (int p=0;p<limit;p++) {
R[p] = R[p/2]/2+((p&1)?limit/2:0);
}
tempexp[0] = (1-tempexp[0]+a[0]+mod)%mod;
for (int p=1;p<n;p++) {
tempexp[p] = (-tempexp[p]+a[p]+mod)%mod;
}
for (int p=n;p<limit;p++) {
tempexp[p] = b[p] = 0;
}
ntt(limit, b, 1);
ntt(limit, tempexp, 1);
for (int p=0;p<limit;p++) {
b[p] = b[p]*tempexp[p]%mod;
}
ntt(limit, b, -1);
for (int p=n;p<limit;p++) {
b[p] = 0;
}
return ;
}
int main() {
scanf("%d", &n);
for (int p=0;p<n;p++) {
scanf("%lld", &a[p]);
}
nttexp(n, b, a);
for (int p=0;p<n;p++) {
printf("%lld ", b[p]);
}
return 0;
}
有没有大佬帮忙看一下啊