Hdu 4656 任意模数FFT

版权声明:By MrBird https://blog.csdn.net/MrBird_to_fly/article/details/82961733

UOJ 模板题提交记录
http://uoj.ac/submission/290654

需要高超的推公式技巧。
使用了叉姐的一份板子 ,侵删。

#include <bits/stdc++.h>
using namespace std;
// double 精度对$10^9+7$ 取模最多可以做到$2^{20}$
const int MOD = 1e6+3;
const double PI = acos(-1);
typedef complex<double> Complex;
typedef long long ll;
const int N = 1<<19, L = 15, MASK = (1 << L) - 1;
Complex w[N];
void FFTInit() {
	for (int i = 0; i < N; ++i) {
		w[i] = Complex(cos(2 * i * PI / N), sin(2 * i * PI / N));
	}
}
void FFT(Complex p[], int n) {
	for (int i = 1, j = 0; i < n - 1; ++i) {
		for (int s = n; j ^= s >>= 1, ~j & s;);
		if (i < j) {
			swap(p[i], p[j]);
		}
	}
	for (int d = 0; (1 << d) < n; ++d) {
		int m = 1 << d, m2 = m * 2, rm = n >> (d + 1);
		for (int i = 0; i < n; i += m2) {
			for (int j = 0; j < m; ++j) {
				Complex &p1 = p[i + j + m], &p2 = p[i + j];
				Complex t = w[rm * j] * p1;
				p1 = p2 - t;
				p2 = p2 + t;
			}
		}
	}
}
Complex A[N], B[N], C[N], D[N];
void mul(int a[N], int b[N]) {
	for (int i = 0; i < N; ++i) {
		A[i] = Complex(a[i] >> L, a[i] & MASK);
		B[i] = Complex(b[i] >> L, b[i] & MASK);
	}
	FFT(A, N), FFT(B, N);
	for (int i = 0; i < N; ++i) {
		int j = (N - i) % N;
		Complex da = (A[i] - conj(A[j])) * Complex(0, -0.5),
				db = (A[i] + conj(A[j])) * Complex(0.5, 0),
				dc = (B[i] - conj(B[j])) * Complex(0, -0.5),
				dd = (B[i] + conj(B[j])) * Complex(0.5, 0);
		C[j] = da * dd + da * dc * Complex(0, 1);
		D[j] = db * dd + db * dc * Complex(0, 1);
	}
	FFT(C, N), FFT(D, N);
	for (int i = 0; i < N; ++i) {
		long long da = (long long)(C[i].imag() / N + 0.5) % MOD,
			 db = (long long)(C[i].real() / N + 0.5) % MOD,
			 dc = (long long)(D[i].imag() / N + 0.5) % MOD,
			 dd = (long long)(D[i].real() / N + 0.5) % MOD;
		a[i] = ((dd << (L * 2)) + ((db + dc) << L) + da) % MOD;
	}
}

int power(int x,ll p){
	int ans=1;
	int base=x;
	while(p){
		if(p&1){
			ans=1ll*ans*base%MOD;
		}
		p>>=1;
		base=1ll*base*base%MOD;
	}
	return ans;
}

int inv(int x){
	return power(x,MOD-2);
}

int u[N],v[N];
int a[N],b,c,d,n;
int fac[N],dpw[N],bpw[N],cpw[N];
int res[N];
int main(){
	FFTInit();
	scanf("%d%d%d%d",&n,&b,&c,&d);
	for(int i=0;i<n;i++)scanf("%d",&a[i]);
	fac[0]=dpw[0]=bpw[0]=cpw[0]=1;
	for(int i=1;i<n;i++){
		fac[i]=1ll*fac[i-1]*i%MOD;
		dpw[i]=1ll*dpw[i-1]*d%MOD;
		bpw[i]=1ll*bpw[i-1]*b%MOD;
		cpw[i]=power(c,1ll*i*i);
	}
	for(int i=0;i<n;i++){
		u[i]=a[i];
		u[i]=1ll*u[i]*dpw[i]%MOD;
		u[i]=1ll*u[i]*fac[i]%MOD;
		v[i]=inv(fac[n-1-i]);
	}
	mul(u,v);
	for(int i=0;i<n;i++){
		res[i]=u[n-1+i];
//		printf("%lld\n",res[i]);
	}
	memset(u,0,sizeof(u));
	memset(v,0,sizeof(v));
	for(int i=0;i<n;i++){
		u[i]=bpw[i];
		u[i]=1ll*u[i]*res[i]%MOD;
		u[i]=1ll*u[i]*cpw[i]%MOD;
		u[i]=1ll*u[i]*inv(dpw[i])%MOD;
		u[i]=1ll*u[i]*inv(fac[i])%MOD;
		v[n+i]=v[n-i]=inv(cpw[i]);
	}
	mul(u,v);
	for(int i=0;i<n;i++){
		printf("%lld\n",1ll*u[n+i]*cpw[i]%MOD);
	}
}

买一送一

#include <bits/stdc++.h>
using namespace std;
// double 精度对$10^9+7$ 取模最多可以做到$2^{20}$
const int MOD = 2e5+3;
const double PI = acos(-1);
typedef complex<double> Complex;
typedef long long ll;
const int N = 1<<19, L = 15, MASK = (1 << L) - 1;
Complex w[N];
void FFTInit() {
	for (int i = 0; i < N; ++i) {
		w[i] = Complex(cos(2 * i * PI / N), sin(2 * i * PI / N));
	}
}
void FFT(Complex p[], int n) {
	for (int i = 1, j = 0; i < n - 1; ++i) {
		for (int s = n; j ^= s >>= 1, ~j & s;);
		if (i < j) {
			swap(p[i], p[j]);
		}
	}
	for (int d = 0; (1 << d) < n; ++d) {
		int m = 1 << d, m2 = m * 2, rm = n >> (d + 1);
		for (int i = 0; i < n; i += m2) {
			for (int j = 0; j < m; ++j) {
				Complex &p1 = p[i + j + m], &p2 = p[i + j];
				Complex t = w[rm * j] * p1;
				p1 = p2 - t;
				p2 = p2 + t;
			}
		}
	}
}
Complex A[N], B[N], C[N], D[N];
void mul(int a[N], int b[N]) {
	for (int i = 0; i < N; ++i) {
		A[i] = Complex(a[i] >> L, a[i] & MASK);
		B[i] = Complex(b[i] >> L, b[i] & MASK);
	}
	FFT(A, N), FFT(B, N);
	for (int i = 0; i < N; ++i) {
		int j = (N - i) % N;
		Complex da = (A[i] - conj(A[j])) * Complex(0, -0.5),
				db = (A[i] + conj(A[j])) * Complex(0.5, 0),
				dc = (B[i] - conj(B[j])) * Complex(0, -0.5),
				dd = (B[i] + conj(B[j])) * Complex(0.5, 0);
		C[j] = da * dd + da * dc * Complex(0, 1);
		D[j] = db * dd + db * dc * Complex(0, 1);
	}
	FFT(C, N), FFT(D, N);
	for (int i = 0; i < N; ++i) {
		long long da = (long long)(C[i].imag() / N + 0.5) % MOD,
			 db = (long long)(C[i].real() / N + 0.5) % MOD,
			 dc = (long long)(D[i].imag() / N + 0.5) % MOD,
			 dd = (long long)(D[i].real() / N + 0.5) % MOD;
		a[i] = ((dd << (L * 2)) + ((db + dc) << L) + da) % MOD;
	}
}

int power(int x,ll p){
	int ans=1;
	int base=x;
	while(p){
		if(p&1){
			ans=1ll*ans*base%MOD;
		}
		p>>=1;
		base=1ll*base*base%MOD;
	}
	return ans;
}

int inv(int x){
	return power(x,MOD-2);
}

int u[N],v[N];
int a[N],b,c,d,n;
int fac[N],dpw[N],bpw[N],cpw[N];
int res[N];
int main(){
	FFTInit();
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d",&n,&b,&d);
		c=2;
		for(int i=0;i<n;i++)scanf("%d",&a[i]);
		fac[0]=dpw[0]=bpw[0]=cpw[0]=1;
		for(int i=1;i<n;i++){
			fac[i]=1ll*fac[i-1]*i%MOD;
			dpw[i]=1ll*dpw[i-1]*d%MOD;
			bpw[i]=1ll*bpw[i-1]*b%MOD;
			cpw[i]=power(c,1ll*i*i);
		}
		memset(u,0,sizeof(u));
		memset(v,0,sizeof(v));
		for(int i=0;i<n;i++){
			u[i]=a[i];
			u[i]=1ll*u[i]*dpw[i]%MOD;
			u[i]=1ll*u[i]*fac[i]%MOD;
			v[i]=inv(fac[n-1-i]);
		}
		mul(u,v);
		for(int i=0;i<n;i++){
			res[i]=u[n-1+i];
			//		printf("%lld\n",res[i]);
		}
		memset(u,0,sizeof(u));
		memset(v,0,sizeof(v));
		for(int i=0;i<n;i++){
			u[i]=bpw[i];
			u[i]=1ll*u[i]*res[i]%MOD;
			u[i]=1ll*u[i]*cpw[i]%MOD;
			u[i]=1ll*u[i]*inv(dpw[i])%MOD;
			u[i]=1ll*u[i]*inv(fac[i])%MOD;
			v[n+i]=v[n-i]=inv(cpw[i]);
		}
		mul(u,v);
		for(int i=0;i<n;i++){
			printf("%lld%c",1ll*u[n+i]*cpw[i]%MOD,i==n-1?'\n':' ');
		}
	}
}

猜你喜欢

转载自blog.csdn.net/MrBird_to_fly/article/details/82961733