钉子精神
查看原帖
钉子精神
100325
peterwuyihong楼主2020/12/26 10:56

NTTNTT

#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr<<#x<<' '<<x<<endl
#ifndef ONLINE_JUDGE
	#define fuck getchar
#else
	#define fuck nc
#endif
char nc(){
  	static char buf[1<<25],*p=buf,*q=buf;
  	if(p==q&&(q=(p=buf)+fread(buf,1,1<<25,stdin),p==q))return EOF;
  	return *p++;
}
template<class T>void read(T&x){
	short f=1;x=0;
	char ch=fuck();
	while(!isdigit(ch)){
		if(ch=='-')f=-1;
		ch=fuck();
	}while(isdigit(ch)){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=fuck();
	}x*=f;
}
template<class T>void write(T x){
	if(x<0)putchar('-'),x=-x;
	if(x>=10)write(x/10);
	putchar(x%10+48);
}
#define int long long
#define maxn 1<<22
int ksm(int a,int b,int p){
	int ans=1;
	for(;b;b>>=1,a=a*a%p)
	if(b&1)ans=ans*a%p;
	return ans;
}
const int P=998244353;
const int G=3;
const int GINV=ksm(3,P-2,P);
int n=1,lena,lenb;
int a[maxn],b[maxn];
int rev[maxn];
void change(int f[],int n){
	for(int i=0;i<n;i++)
	if(rev[i]>i)swap(f[i],f[rev[i]]);
}
void ntt(int f[],int n,int on){
	change(f,n);
	for(int h=2;h<=n;h<<=1){
		int step=ksm(G,(P-1)/h,P);
		for(int i=0;i<n;i+=h){
			int w=1;
			for(int j=i;j<i+h/2;j++){
				int G=f[j];
				int H=f[j+h/2];
				f[j]=(G+w*H)%P;
				f[j+h/2]=(G-w*H%P+P)%P;
				w=w*step%P;
			}
		}
	}
	if(on==-1){
		reverse(f+1,f+n);
		int inv=ksm(n,P-2,P);
		for(int i=0;i<n;i++)f[i]=f[i]*inv%P;
	}
}
signed main(){
	read(lena),read(lenb);
	lena++,lenb++;
	for(int i=0;i<lena;i++)read(a[i]);
	for(int i=0;i<lenb;i++)read(b[i]);
	while(n<lena||n<lenb)n<<=1;n<<=1;
	for(int i=0;i<n;i++){
		rev[i]=rev[i>>1]>>1;
		if(i&1)rev[i]|=n>>1;
	}
	ntt(a,n,1),ntt(b,n,1);
	for(int i=0;i<n;i++)a[i]=a[i]*b[i]%P;
	ntt(a,n,-1);
	for(int i=0;i<lena+lenb-1;i++)write(a[i]),putchar(' ');
}

#1

为什么NTTNTTreversereverse这一步而FTTFTT没有??

if(on==-1){
	reverse(f+1,f+n);
	int inv=ksm(n,P-2,P);
	for(int i=0;i<n;i++)f[i]=f[i]*inv%P;
}

#2

为什么取单位根时NTTNTT不用取倒数??

int step=ksm(G,(P-1)/h,P);

#3

为什么上面一句改成

int step=ksm(GINV,(P-1)/h,P);

还能ACAC

求助dalaodalao,我真的方极了

2020/12/26 10:56
加载中...