NTT本地正确评测全WA求调
查看原帖
NTT本地正确评测全WA求调
489661
lateworker楼主2023/12/14 17:05

NTT本地正确评测全WA求调

#include <iostream>
#include <cstring>
using namespace std;
namespace std {
#define int long long
	struct _NTT {
		const int P = 998244353, G = 3, Gi = 332748118;
		int *r; int len, l;
		_NTT(int s) { init(s); }
		~_NTT() { delete []r; }
		inline void init(int s) {
			for(len=1,l=0;len<=s;len<<=1,++l);
			r = new int[len+10];
			memset(r, 0, sizeof(*r));
			for(int i=0;i<len;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
		}
		inline void qpow(int a, int b, int &ret) { while(b) { if(b&1) ret*=a,ret%=P; a*=a,b>>=1,a%=P; } }
		inline void NTT(int *num, int t) {
			for(int i=0;i<len;++i) 
				if(i<r[i]) swap(num[i],num[r[i]]);
			for(int mid=1;mid<len;mid<<=1) {
				int Wn=1,w=1; qpow(t==1?G:Gi,(P-1)/(mid<<1),Wn);
				for(int j=0;j<len;j+=(mid<<1),w=1)
					for(int k=0,x,y;k<mid;++k,w=(w*Wn)%P)
						x=num[j+k], y=w*num[j+k+mid]%P,
						num[j+k]=(x+y)%P,
						num[j+k+mid]=(x-y+P)%P;
			}
			if(t == -1){
				int inv=1; qpow(len,P-2,inv);
				for(int i=0;i<=len;++i) num[i]=num[i]*inv%P;
			}
		}
	};
	struct Int {
		int *val, typ; int len, siz; 
		Int(int s) { init(s); }
		~Int() { delete []val; }
		inline void init(int s) { typ=0,len=0,siz=s,val=new int[s+10],memset(val,0,sizeof(*val)); }
		#define _digit(x) ('0'<=x&&x<='9')
		inline void _adjust() {
			for(int i=0;i<len;++i) 
				if(val[i]>=10) val[i+1]+=val[i]/10,val[i]%=10;
			while(val[len-1]==0) --len;
		}
		inline void _input() {
			len=0,typ=0,val[0]=getchar();
			if(val[0]=='-') typ=1,val[0]=getchar();
			while(_digit(val[len]))
				val[len++]^=48, val[len]=getchar();
			val[len] = 0;
			for(int i=0;i<len/2;++i) swap(val[i],val[len-i-1]);
			_adjust();
		}
		inline void _output() {
			if(typ) putchar('-');
			for(int i=len-1;i>=0;--i) putchar(val[i]^48);
		}
	};
	inline void Int_multiply(Int &a, Int &b, Int &c, _NTT &mul) {
		c.len=a.len+b.len;
		mul.NTT(a.val, 1), mul.NTT(b.val, 1);
		for(int i=0;i<mul.len;++i) c.val[i] = a.val[i]*b.val[i]%mul.P;
		mul.NTT(a.val, -1), mul.NTT(b.val, -1);
		if((&c)!=(&a)&&(&c)!=(&b)) mul.NTT(c.val, -1);
		c._adjust();
	}
	istream &operator>> (istream &in, Int &a) {a._input();return in;}
	ostream &operator<< (ostream &out, Int &a) {a._output();return out;}
#undef int
};
const int N = 3e6+10;
Int a(N), b(N), c(N);
int main() {
	cin>>a>>b;
	_NTT mul(a.len+b.len+1000);
	Int_multiply(a, b, c, mul);
	cout<<c; 
	return 0;
}
2023/12/14 17:05
加载中...