为什么这里不能加等号
查看原帖
为什么这里不能加等号
383782
StarPatrick楼主2023/4/23 15:03

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

有没有大佬帮忙看一下啊

2023/4/23 15:03
加载中...