版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/90294174
看完基本理论之后就全是细节问题了。
1.有n次单位根可以DFT后做长度为n的循环卷积。
2.多维的把单位根乘起来就行。
3.没有n次单位根?复数精度不够,模意义下,模数居然是个
如此不友善,那么有一个通法:
的意义下的多项式,
次单位根为
,这个。。。
好暴力啊,如果不是多维卷积,这个是
还不如暴力卷。
可以省掉一个2的常数,用它的分圆多项式
如果你想,还可以继续把原式分解因式找有没有
次单位根。。。。。
这题就凑合用分圆多项式做模式吧。(还可以用5的分圆多项式
,然后直接拿
做模式,乘单位根的时候可以直接位移少了一个5的常数,最后再
)
4.有没有n的逆元?上面大佬博客讲的很清楚。
5.怎么DFT?分状态像DP一样高维求和就行了。
总结:有了(形式方便运算的)n次单位根就是有了一切。
AC Code:
#include<bits/stdc++.h>
#define ull unsigned long long
#define maxn 100000
#define BASE 10
using namespace std;
struct cplx{
ull a[5];
cplx(ull a0=0,ull a1=0,ull a2=0,ull a3=0,ull a4=0){ a[0]=a0,a[1]=a1,a[2]=a2,a[3]=a3,a[4]=a4; }
cplx operator +(const cplx &B)const{
cplx ret;
for(int i=0;i<5;i++) ret.a[i]=a[i]+B.a[i];
return ret;
}
cplx operator -(const cplx &B)const{
cplx ret;
for(int i=0;i<5;i++) ret.a[i]=a[i]-B.a[i];
return ret;
}
cplx operator *(const cplx &B)const{
static ull ar[10];
memset(ar,0,sizeof ar);
for(int i=0;i<5;i++) if(a[i])
for(int j=0;j<5;j++) if(B.a[j])
ar[(i+j)%5] += a[i] * B.a[j];
return cplx(ar[0],ar[1],ar[2],ar[3],ar[4]);
}
cplx muldwg(int num){
cplx ret;
for(int i=0;i<5;i++) ret.a[(num+i)%5] = (num&1)?-a[i]:a[i];
return ret;
}
}a[maxn];
cplx Pow(cplx base,ull k){
cplx ret=cplx(1,0,0,0,0);
for(;k;k>>=1,base=base*base)
if(k&1)
ret=ret*base;
return ret;
}
ull Pow(ull base,ull k){
ull ret;
for(;k;k>>=1,base=base*base)
if(k&1)
ret=ret*base;
return ret;
}
int n;
void DFT(cplx *A,int tp){
int res = (tp == 1 ? 1 : BASE-1);
for(int L=1;L<maxn;L*=BASE)
for(int offset=0;offset<maxn;offset++)
if(offset/L%BASE==0){
cplx tmp[BASE];
for(int i=0;i<BASE;i++)
for(int j=0;j<BASE;j++)
tmp[i] = tmp[i] + (a[offset+j*L].muldwg(i*j*res%BASE));
for(int i=0;i<BASE;i++)
a[offset+i*L]=tmp[i];
}
}
int main(){
cout<<(1ull<<63)*2<<endl;
cin>>n;
for(int i=0;i<n;i++){
int x;cin>>x;
a[x].a[0]++;
}
DFT(a,1);
for(int i=0;i<maxn;i++){
a[i] = Pow(a[i],n);
}
DFT(a,-1);
ull inv5 = 6723469279985657373ULL;
for(int i=0;i<n;i++){
ull tmp = (a[i].a[0] - a[i].a[4]) * inv5 / 32ull % (1ull<<58);
cout<<tmp<<endl;
}
}