今天的A题,裸的ntt,但我不会,于是白送了50分。
于是跑来学一下ntt。
题面很简单,就懒得贴了,那不是我要说的重点。
重点是NTT,也称快速数论变换。
在很多问题中,我们可能会遇到在模意义下的多项式乘法问题,这时传统的快速傅里叶变换可能就无法满足要求,这时候快速数论变换就派上了用场。
考虑快速傅里叶变换的实现,利用单位复根的特殊性质来减少运算,而利用的,就是dft变换的循环卷积特性。于是考虑在模意义下同样具有循环卷积特性的东西。
考虑在模p意义下(
我们令
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
const int inf=0x3f3f3f3f;
int getint()
{
int f=1,g=0;char c=getchar();
while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
while(c>=‘0‘ && c<=‘9‘)g=(g<<3)+(g<<1)+c-‘0‘,c=getchar();
return f*g;
}
const int maxn=1<<16;
const int G=7;
const int mod=950009857;
int inv;
int w[2][maxn];
int N,m,k;
int rev[maxn];
int n;
int cnt;
ll power(ll x,ll y)
{
ll res=1ll;
for(;y;y>>=1,x=(x*x)%mod)
{
if(y&1)res=res*x%mod;
}
return res;
}
void init()
{
for(n=1;n<N<<1;n<<=1,cnt++);inv=power(n,mod-2);
w[0][0]=w[0][n]=w[1][0]=w[1][n]=1;
int g=power(G,(mod-1)/n);
for(int i=1;i<=n-1;i++)
{
w[0][i]=(ll)w[0][i-1]*g%mod;
}
for(int i=0;i<=n;i++)
{
w[1][i]=w[0][n-i];
}
for(int i=0;i<=n;i++)
{
int temp=i;int pos=0;
for(int j=1;j<=cnt;j++)
{
pos<<=1;pos |=temp&1;temp>>=1;
}
rev[i]=pos;
}
}
void fft(int a[],int n,int v)
{
int i,j,l;
for(i=0;i<n;i++)
{
if(i>rev[i])swap(a[i],a[rev[i]]);
}
for(i=2;i<=n;i<<=1)
{
int mid=i>>1;
for(j=0;j<n;j+=i)
{
for(l=0;l<mid;l++)
{
int t=(ll)a[j+l+mid]*w[v][(n/i)*l]%mod;
a[j+l+(mid)]=((ll)a[j+l]-t+mod)%mod;
a[j+l]=((ll)a[j+l]+t)%mod;
}
}
}
}
int main()
{
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/starry__night/article/details/46808195