最近想写一下多项式取模的模板,然而找不到模板题。于是上网找了个高精度除法题,写完之后才发现高精度除法和多项式取模是不一样的QAQ。前者要求不能出现负数,为此某些位置可以暂时为0,将余数拉到后面;而多项式取模则要求最高项一定要剩余0。
于是我把程序随便改了改,先扔在这儿,以后备忘。我写的是实数(FFT)的版本(其实我并不知道实数版本的多项式取模到底有什么用)。
另外我还不知道有没有写错,过了几组手造的小数据就不管了……
CODE:
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1000000;
const double pi=acos(-1.0);
struct Complex
{
double X,Y;
Complex (double a=0.0,double b=0.0) : X(a),Y(b) {}
} ;
Complex operator+(Complex a,Complex b){return Complex(a.X+b.X,a.Y+b.Y);}
Complex operator-(Complex a,Complex b){return Complex(a.X-b.X,a.Y-b.Y);}
Complex operator*(Complex a,Complex b){return Complex(a.X*b.X-a.Y*b.Y,a.X*b.Y+a.Y*b.X);}
Complex A[maxn];
Complex B[maxn];
int Rev[maxn];
int N,Lg;
double F[maxn];
int G[maxn];
double ans[maxn];
double Mod[maxn];
char s[maxn];
int h[maxn];
int ln,lm;
void DFT(Complex *a,double f)
{
for (int i=0; iif (ifor (int len=2; len<=N; len<<=1)
{
int mid=(len>>1);
double ang=2.0*pi/(double)len;
Complex e( cos(ang) , f*sin(ang) );
for (Complex *p=a; p!=a+N; p+=len)
{
Complex wn(1.0,0.0);
for (int i=0; ivoid FFT(bool rev)
{
for (int i=0; i0;
for (int j=0; jif (i&(1<1<<(Lg-j-1));
}
DFT(A,1.0);
DFT(B,1.0);
if (rev) for (int i=0; ifor (int i=0; i1.0);
for (int i=0; idouble)N;
}
void Poly_Rev(int m)
{
if (m==1) F[0]=1.0/(double)G[0];
else
{
Poly_Rev(m>>1);
N=2*m,Lg=0;
while ((1<for (int i=0; i0.0),B[i]=Complex(G[i],0.0);
for (int i=m; i0.0,0.0);
FFT(true);
for (int i=0; i2.0*F[i]-A[i].X;
}
}
int main()
{
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
scanf("%d",&ln);
for (int i=ln-1; i>=0; i--) scanf("%d",&h[i]);
scanf("%d",&lm);
for (int i=lm-1; i>=0; i--) scanf("%d",&G[i]);
N=1;
while (N3) N<<=1;
Poly_Rev(N);
ln=ln-lm+1;
N=1,Lg=0;
while (N<2*ln+2) N<<=1,Lg++;
for (int i=0; i0.0),B[i]=Complex(h[i],0.0);
for (int i=ln; i0.0,0.0);
FFT(false);
for (int i=0; ifor (int i=0; i1; i++) swap(ans[i],ans[ln-i-1]);
for (int i=0; iprintf("%.3lf ",ans[i]);
printf("\n");
N=1,Lg=0;
while (N2) N<<=1,Lg++;
for (int i=0; i0.0,0.0);
for (int i=0; i0.0);
for (int i=0; i1],0.0);
FFT(false);
for (int i=0; i1; i++) Mod[i]=h[ln+lm-i-2]-A[i].X;
for (int i=0; i1; i++) printf("%.3lf ",Mod[i]);
printf("\n");
return 0;
}