QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#522623#622. 多项式多点求值ucup-team100420 4394ms299452kbC++147.1kb2024-08-17 09:11:382024-08-17 09:11:39

Judging History

你现在查看的是最新测评结果

  • [2024-08-17 09:11:39]
  • 评测
  • 测评结果:20
  • 用时:4394ms
  • 内存:299452kb
  • [2024-08-17 09:11:38]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
#ifdef DEBUG
#include"debug.h"
#else
#define debug(...) void()
#endif
#define all(x) (x).begin(),(x).end()
template<class T>
auto ary(T *a,int l,int r){
	return vector<T>{a+l,a+1+r};
}
using ll=long long;
using ull=unsigned long long;
using LL=__int128;
const int mod=998244353;
ll qpow(ll x,ll y=mod-2,ll ans=1){
	for(;y;(x*=x)%=mod,y>>=1)if(y&1)(ans*=x)%=mod;
	return ans;
}
mt19937 rnd(time(0));
int sqr(int n){
	int a,val;
	auto chk=[&](int x){
		return qpow(x,(mod-1)/2)==1;
	};
	do a=rnd()%mod;while(chk(val=(1ll*a*a-n)%mod));
	struct comp{
		int x,y;
		comp(int a=0,int b=0):x(a),y(b){}
		comp operator + (const comp &a)const{
			return comp((x+a.x)%mod,(y+a.y)%mod);
		}
	}x(a,1),ans(1,0);
	auto mul=[&](comp a,comp b){
		return comp((1ll*a.x*b.x+1ll*a.y*b.y%mod*val)%mod,(1ll*a.x*b.y+1ll*a.y*b.x)%mod);
	};
	int y=(mod+1)/2;
	for(;y;x=mul(x,x),y>>=1)if(y&1)ans=mul(ans,x);
	return min(ans.x,mod-ans.x);
}
namespace Poly{
	const int N=1<<21,g=3;
	int lim,rev[N],A[N],B[N],pw[N];
	void init(int n){
		for(lim=1;lim<n;lim<<=1);
		for(int i=1;i<lim;i++)rev[i]=rev[i>>1]>>1|(i&1?lim>>1:0);
	}
	void Init(){
		int x=qpow(g,(mod-1)/N);
		pw[N/2]=1;
		for(int i=N/2+1;i<N;i++)pw[i]=1ll*pw[i-1]*x%mod;
		for(int i=N/2-1;i;i--)pw[i]=pw[i<<1];
	}
	namespace Public{
		using poly=vector<int>;
		void NTT(int *f,int op){
			static unsigned long long a[N];
			for(int i=0;i<lim;i++)a[i]=f[rev[i]];
			for(int len=1,x;len<lim;len<<=1){
				for(int i=0;i<lim;i+=len<<1){
					for(int j=0;j<len;j++){
						x=a[i|j|len]*pw[len|j]%mod;
						a[i|j|len]=a[i|j]+mod-x,a[i|j]+=x;
					}
				}
				if(len>>16&1){
					for(int i=0;i<lim;i++)a[i]%=mod;
				}
			}
			for(int i=0;i<lim;i++)f[i]=a[i]%mod;
			if(op<0){
				reverse(f+1,f+lim);
				int x=qpow(lim);
				for(int i=0;i<lim;i++)f[i]=1ll*f[i]*x%mod;
			}
		}
		poly operator * (const poly &a,const poly &b){
			int n=a.size(),m=b.size(),k=n+m-1;
			init(k);
			copy(all(a),A),fill(A+n,A+lim,0);
			copy(all(b),B),fill(B+m,B+lim,0);
			poly c(k);
			NTT(A,1),NTT(B,1);
			for(int i=0;i<lim;i++)A[i]=1ll*A[i]*B[i]%mod;
			NTT(A,-1);
			for(int i=0;i<k;i++)c[i]=A[i];
			return c;
		}
		poly& operator *= (poly &a,const poly &b){
			return a=a*b;
		}
		poly& operator += (poly &a,const poly &b){
			int n=a.size(),m=b.size();
			if(n<m)a.resize(m);
			for(int i=0;i<m;i++)(a[i]+=b[i])%=mod;
			return a;
		}
		poly operator + (const poly &a,const poly &b){
			poly c(a);
			return c+=b;
		}
		poly& operator -= (poly &a,const poly &b){
			int n=a.size(),m=b.size();
			if(n<m)a.resize(m);
			for(int i=0;i<m;i++)(a[i]+=mod-b[i])%=mod;
			return a;
		}
		poly operator - (const poly &a,const poly &b){
			poly c(a);
			return c-=b;
		}
		poly operator - (const poly &a){
			return poly()-a;
		}
		poly& operator *= (poly &a,const int &b){
			for(int &x:a)x=1ll*x*b%mod;
			return a;
		}
		poly operator * (const poly &a,const int &b){
			poly c(a);
			return c*=b;
		}
		poly& operator /= (poly &a,const int &b){
			return a*=qpow(b);
		}
		poly operator / (const poly &a,const int &b){
			poly c(a);
			return c/=b;
		}
		poly& operator %= (poly &a,const int &b){
			if(a.size()>b)a.resize(b);
			return a;
		}
		poly operator % (const poly &a,const int &b){
			poly c(a);
			return c%=b;
		}
		poly inv(const poly &a,int n=-1){
			if(n==-1)n=a.size();
			if(n==1)return poly(1,qpow(a[0]));
			int m=(n+1)/2;
			auto b=inv(a%m,m);
			return b*(poly{2}-a*b%n)%n;
		}
		poly deriv(const poly &a){
			int n=a.size();
			if(!n)return poly();
			poly b(n-1);
			for(int i=1;i<n;i++)b[i-1]=1ll*a[i]*i%mod;
			return b;
		}
		poly integ(const poly &a){
			int n=a.size();
			if(!n)return poly(1);
			poly b(n+1);
			b[1]=1;
			for(int i=2;i<=n;i++)b[i]=1ll*b[mod%i]*(mod-mod/i)%mod;
			for(int i=1;i<=n;i++)b[i]=1ll*b[i]*a[i-1]%mod;
			return b;
		}
		poly ln(const poly &a,int n=-1){
			if(n==-1)n=a.size();
			return integ(deriv(a)%n*inv(a,n)%n)%n;
		}
		poly exp(const poly &a,int n=-1){
			if(n==-1)n=a.size();
			if(n==1)return poly{1};
			int m=(n+1)/2;
			auto b=exp(a%m,m);
			return b*(poly{1}+a-ln(b,n))%n;
		}
		poly sqrt(const poly &a,int n=-1){
			if(n==-1)n=a.size();
			if(n==1)return poly(1,sqr(a[0]));
			int m=(n+1)/2;
			auto b=sqrt(a%m,m);
			return (a*inv(b,n)%n+b)*(mod+1>>1);
		}
		poly operator << (const poly &a,const int &b){
			poly c(a.size()+b);
			copy(all(a),c.begin()+b);
			return c;
		}
		poly& operator <<= (poly &a,const int &b){
			return a=a<<b;
		}
		poly operator >> (const poly &a,const int &b){
			if(b>=a.size())return poly();
			return poly{a.begin()+b,a.end()};
		}
		poly& operator >>= (poly &a,const int &b){
			return a=a>>b;
		}
		poly qpow(const poly &a,const ll &b,int k=-1){
			if(a.empty())return poly();
			if(!~k)k=a.size();
			int n=a.size(),st=0;
			for(;st<n&&!a[st];st++);
			if(st==n||(LL)st*b>=k)return poly(k);
			if(st)return qpow(a>>st,b,k-st*b)<<st*b;
			int x=a[0];
			return exp(ln(a/x,k)*(b%mod),k)*::qpow(x,b);
		}
		poly operator / (const poly &a,const poly &b){
			int n=a.size(),m=b.size(),k=n-m+1;
			if(k<=0)return poly();
			poly c(a),d(b);
			reverse(all(c));
			reverse(all(d));
			c=c%k*inv(d,k)%k;
			reverse(all(c));
			return c;
		}
		poly operator % (const poly &a,const poly &b){
			if(a.size()<b.size())return a;
			poly c=a/b;
			return (a-b*c)%(b.size()-1);
		}
		poly& operator %= (poly &a,const poly &b){
			return a=a%b;
		}
		void div(const poly &a,const poly &b,poly &c,poly &d){
			if(a.size()<b.size())return c=poly(),d=a,void();
			c=a/b,d=(a-b*c)%(b.size()-1);
		}
		poly mulT(const poly &a,const poly &b){
			int n=a.size(),m=b.size();
			if(n<m)return poly();
			init(n);
			copy(all(a),A),fill(A+n,A+lim,0);
			copy(all(b),B),reverse(B,B+m),fill(B+m,B+lim,0);
			NTT(A,1),NTT(B,1);
			for(int i=0;i<lim;i++)A[i]=1ll*A[i]*B[i]%mod;
			NTT(A,-1);
			int k=n-m+1;
			poly c(k);
			for(int i=0;i<k;i++)c[i]=A[i+m-1];
			return c;
		}
		poly multipoint(const poly &a,const poly &x){
			if(x.empty())return poly();
			vector<poly>t;
			t.reserve(x.size()*2-1);
			poly ls(x.size()*2-1),rs(ls);
			function<int(int,int)>init=[&](int l,int r){
				int k=t.size();
				t.push_back(poly());
				if(l==r)return t[k]={1,(mod-x[l])%mod},k;
				int mid=(l+r)>>1;
				ls[k]=init(l,mid),rs[k]=init(mid+1,r);
				return t[k]=t[ls[k]]*t[rs[k]],k;
			};
			init(0,x.size()-1);
			poly ans(x.size());
			int cur=0;
			function<void(poly,int,int)>solve=[&](poly a,int l,int r){
				int k=cur++;
				if(l==r)return ans[l]=a[0],void();
				int mid=(l+r)>>1;
				solve(mulT(a,t[rs[k]]),l,mid);
				solve(mulT(a,t[ls[k]]),mid+1,r);
			};
			auto a_=a;
			a_.resize(x.size()*2);
			solve(mulT(a_,inv(t[0])),0,x.size()-1);
			return ans;
		}
	}
}
using namespace Poly::Public;
int n,m;
int main(){
	Poly::Init();
	scanf("%d%d",&n,&m);
	poly a(n);
	for(int &x:a)scanf("%d",&x);
	poly b(m);
	for(int &x:b)scanf("%d",&x);
	auto res=multipoint(a,b);
	for(int x:res)printf("%d\n",x);
	return 0;
}
#ifdef DEBUG
#include"debug.hpp"
#endif

Details

Tip: Click on the bar to expand more detailed information

Pretests


Final Tests

Test #1:

score: 0
Wrong Answer
time: 7ms
memory: 16552kb

input:

100 94
575336069 33153864 90977269 80162592 25195235 334936051 108161572 14050526 356949084 797375084 805865808 286113858 995555121 938794582 458465004 379862532 563357556 293989886 273730531 13531923 113366106 126368162 405344025 443053020 475686818 734878619 338356543 661401660 834651229 527993675...

output:

631625726
397488316
278333202
923032879
660142564
14566144
953205371
914729681
166172035
379851217
863677370
442720416
974052604
913085241
989080556
752152518
21295512
34919792
53202570
195089279
605456350
958124491
277993757
378280856
446542263
416419784
47152152
83227232
432934282
205548133
396551...

result:

wrong answer 1st numbers differ - expected: '940122667', found: '631625726'

Test #2:

score: 20
Accepted
time: 22ms
memory: 18044kb

input:

5000 4999
410683245 925831211 726803342 144364185 955318244 291646122 334752751 893945905 484134283 203760731 533867267 813509277 491860093 413174124 584582617 594704162 976489328 978500071 196938934 628117769 169796671 858963950 562124570 582491326 647830593 238623335 20782490 674939336 656529076 2...

output:

683038054
713408290
776843174
52275065
602085453
905088100
991748340
720305324
831850056
296147844
79380797
882313010
941965313
987314872
363655479
380838721
51243733
165728533
592641557
679475455
651115426
60492203
787012426
247557193
136399242
484592897
908383514
735275879
648228244
443933835
5504...

result:

ok 4999 numbers

Test #3:

score: 0
Wrong Answer
time: 87ms
memory: 23852kb

input:

30000 29995
536696866 881441742 356233606 594487396 991820796 695996817 7219464 149265950 843761437 329761701 260625152 80366362 598729314 133794090 12808683 67477659 320740422 878134577 879383179 940923483 660160621 18082378 886078389 524050341 35092018 137623841 988429688 258507355 138475726 75726...

output:

934511191
115887316
789878969
801068653
433356127
739015543
175905809
88133757
934381363
650992259
781959777
755919872
430296480
972253933
902561656
157937927
194984375
683334874
887464592
913431359
269717692
72454893
359793164
605366094
895784810
743596987
34423237
695316754
341858791
41529367
7154...

result:

wrong answer 1st numbers differ - expected: '319541931', found: '934511191'

Test #4:

score: 0
Wrong Answer
time: 381ms
memory: 43468kb

input:

100000 99989
703908936 826436271 431732352 607460686 960390248 897906950 506352459 662618885 172508812 713410533 704313866 156459539 879660919 98030681 46358006 400134234 121190289 498201666 616888945 210891377 39623412 687350951 269444705 980768130 381802923 553892268 644461704 287608268 554761733 ...

output:

853172084
353546759
706129709
457632775
417509103
269924014
721243214
579093262
270457076
638244667
269829046
864998229
117362452
97226981
518735462
482259593
503859950
371347748
965753503
764243801
815598529
990255771
730267000
292945738
879187502
221486609
764116106
741376315
381705926
388939916
6...

result:

wrong answer 1st numbers differ - expected: '135579851', found: '853172084'

Test #5:

score: 0
Wrong Answer
time: 4394ms
memory: 299452kb

input:

1000000 999998
326289172 459965021 432610030 381274775 890620650 133203219 755508578 820410129 100497878 978894337 34545975 484258543 341383383 556328539 705716773 985485996 201697555 806763870 456757110 445252781 501965590 655584951 516373423 475444481 554722275 106826011 433893131 385018453 687541...

output:

489125153
699695308
119721343
730172127
527068209
129726044
964210833
313103362
363518718
617040841
167255493
622443149
32167629
236812666
830893716
150048583
31065362
369358872
757318196
150682453
827615207
675863896
453840793
263212355
438346798
312643804
881508045
338457253
657293889
243330935
12...

result:

wrong answer 1st numbers differ - expected: '606800783', found: '489125153'