题目
Description
Input
Output
Sample Input
样例输入 1:
2
7
-7
14
样例输入 2:
3
1
4
1
5
样例输入 3:
0
998244353
Sample Output
样例输出 1:
2
7
样例输出 2:
样例输出 3:
998244353
Data Constraint
更新:N<10^5
Hint
更新:N<10^5
思路
充分性:考虑p|f(x),即f(x)=kp,即在modp意义下,f(x)=0,根据欧拉定理,分两种情况讨论
x<p,又因为p是质数,那么显然有(x,p)=1,那么xp−1≡1(modp),有xp−x≡0(modp)
x≥p,如果gcd(x,p)不为1,那么显然有gcd(x,p)=p,那么已经满足p|f(x),否则套用欧拉定理
必要性:如果p|f(x),那么0,1,⋯,p−1必然为f(x)的一个根,那么f(x)有因式x(x−1)(x−2)⋯(x−(p−1))。我们考虑这个因式与xp−x是等价的,如果不是等价的,那么作差之后,最高次变为p−1,而根的个数却有p个,显然矛盾
代码
#pragma GCC optimize(3)
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;
const int N=1e5+77;
ll n,a[N],mx,b[100077],cnt,c[N];
ll f[N];
inline void init()
{
for (int i=2; i<=mx; i++)
{
if(!f[i]) b[++cnt]=i;
for (int j=1; j<=cnt && (j==1 || i%(b[j-1])) && b[j]*i<=mx; j++)
f[b[j]*i]=-1;
}
ll s=0;
for(int i=1; i<=cnt; i++) s+=b[i];
}
signed main()
{
freopen("poly.in","r",stdin); freopen("poly.out","w",stdout);
scanf("%lld",&n);
for(register int i=n; i>=0; i--) scanf("%lld",&a[i]);
mx=n+1;
init();
for(register int x=1; x<=cnt; x++)
{
bool bz=1;
for(int i=0; i<=n; i++) c[i]=a[i];
for(register int i=n; i>=b[x]; i--)
c[i-b[x]+1]+=c[i],c[i]=0;
for(register int i=0; i<=n; i++) if(c[i]%b[x]!=0)
{
bz=0; break;
}
if(bz) printf("%lld\n",b[x]);
}
cnt=0;
int t=abs(a[n]),tt=sqrt(t);
for(register int i=2; i<=tt; i++)
{
if(t%i==0)
{
while(t%i==0) t/=i;
if(i>mx)b[++cnt]=i;
}
}
if(t>mx) b[++cnt]=t;
for(register int i=1; i<=cnt; i++)
{
bool bz=1;
for(register int j=0; j<n; j++) if(a[j]%b[i]!=0)
{
bz=0; break;
}
if(bz) printf("%lld\n",b[i]);
}
}