社区讨论
拆系数FFT求助(精度问题)
P4245【模板】任意模数多项式乘法参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mkf79y0p
- 此快照首次捕获于
- 2026/01/15 16:41 上个月
- 此快照最后确认于
- 2026/01/18 10:35 上个月
本人在突破50pts大关后屡次90,95分,虽然有longdouble的加持但仍旧先后WA了:15&17,16,11,12(修改了拆的系数),但同为5次FFT,为什么我的代码困于精度问题而非时间,求高人提升精度🙏(或找出原因
CPP#include <bits/stdc++.h>
using namespace std;
struct Cp{
long double a,b;
Cp(long double x,long double y):a(x),b(y){}
Cp(){}
Cp operator+(Cp x){return(Cp){x.a+a,x.b+b};}
Cp operator-(Cp x){return(Cp){a-x.a,b-x.b};}
Cp operator*(Cp x){return(Cp){a*x.a-b*x.b,a*x.b+b*x.a};}
};
const int P=65000,N=3e5+10;
int r[N],lim,l,n,m,p;
int a[N],b[N];
const long double pi=3.1415926535897932384626;
void fft(Cp*A,int type){
for(int i=0;i<lim;i++){
if(i<r[i])swap(A[i],A[r[i]]);
}
for(int mid=1;mid<lim;mid<<=1){
Cp Wn(cos(pi/mid),type*sin(pi/mid));
for(int j=0,R=mid<<1;j<lim;j+=R){
Cp w(1,0);
for(int k=0;k<mid;k++,w=w*Wn){
Cp x=A[j+k],y=w*A[j+k+mid];
A[j+k]=x+y;
A[j+k+mid]=x-y;
}
}
}
}
Cp a1[N],a2[N];
int ans[N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m>>p;
for(lim=1;lim<=n+m;++l,lim<<=1);
for(int i=0;i<lim;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
for(int i=0;i<=n;i++)cin>>a[i],a[i]%=p;
for(int i=0;i<=m;i++)cin>>b[i],b[i]%=p;
for(int i=0;i<lim;i++)a1[i].a=a[i]%P,a1[i].b=a[i]/P;
for(int i=0;i<lim;i++)a2[i].a=b[i]%P,a2[i].b=b[i]/P;
fft(a1,1),fft(a2,1);
for(int i=0;i<lim;i++)a1[i]=a1[i]*a2[i];
fft(a1,-1);
for(int i=0;i<lim;i++)a2[i].a=a[i]/P,a2[i].b=b[i]/P;
fft(a2,1);
for(int i=0;i<lim;i++)a2[i]=a2[i]*a2[i];
fft(a2,-1);
long long tmp=(1ll*P*P+1)%p;
for(int i=0;i<lim;i++){
ans[i]=((long long)(a1[i].b/lim+0.5))%p*P%p;
}
for(int i=0;i<lim;i++){
ans[i]+=(((long long)(a1[i].a/lim+0.5)%p)+tmp*((long long)(a2[i].b/lim/2+0.5)%p))%p;
ans[i]%=p;
}
for(int i=0;i<=n+m;i++){
cout<<ans[i]<<' ';
}
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...