AtCoderP137F Folynomial Consruction
Posted sillytiet
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoderP137F Folynomial Consruction相关的知识,希望对你有一定的参考价值。
数论
由于p是素数,考虑到费马小定理:
\[ a^p-1 \equiv 1 (mod p) \]
而再观察,函数\(f(x)\)要求的值都是0或1
那么,将费马小定理变一下:
\[ (x-i)^p-1 \equiv 1 (mod p)(x \neq i) \]
\[ (x-i)^p-1 \equiv 0 (mod p)(x = i) \]
我们定义一个p-1次多项式\(g(x)=b_0+b_1 \times x+b_2 \times x^2+...+b_p-1 \times x^p-1\),且该多项式初始值为0
那么,对于一个\(A_i\),若\(A_i=1\),我们可以在\(g(x)\)中加上\(1-(x-i)^p-1\)。因为根据上述式子,我们可以得知在模p下,当且仅当x=i时,\(1-(x-i)^p-1\)的值才为1,否则都为0。也就是说,\(1-(x-i)^p-1\)只会影响x=i的情况(将其值变为1)。
然后在多项式展开就行了。
代码(注意负数取模):
#include<bits/stdc++.h>
using namespace std;
int n,A[10100],cnt[10010],ans[10100],C[3000][3000];
void init()
C[0][0]=1;
for(int i=1;i<=n;i++)
C[i][0]=1;
for(int j=1;j<=i;j++)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%n;
int main()
scanf("%d",&n);
init();
for(int i=0;i<n;i++)scanf("%d",&A[i]);
for(int i=0;i<n;i++)
if(A[i]==1)cnt[i]++,ans[0]++;
for(int i=0;i<n;i++)
if(cnt[i]==0)continue;
for(int j=0,po=1;j<n;j++)
int res=C[n-1][j]*po;
res%=n;
if(res<0)
int tmp=abs(res);
res=(n-tmp%n)%n;
else res=res%n;
ans[n-1-j]=(ans[n-1-j]+n-res)%n;
po=po*(-i);
if(po<0)
int tmp=abs(po);
po=(n-tmp%n)%n;
else po=po%n;
for(int i=0;i<n;i++)printf("%d ",ans[i]);
return 0;
以上是关于AtCoderP137F Folynomial Consruction的主要内容,如果未能解决你的问题,请参考以下文章