判断一个关于n的多项式是否在n取所有正整数时都是D的倍数。
如关于n的多项式2n+2在n取所有正整数时都是2的倍数,而不都是3的倍数。
是否都是D的倍数,最好的方法就是证明多项式是一个等差数列,且首相和公差都是D的倍数即可。
设k为多项式的次数。
当k=0时,多项式是一个常数,因此只需要判断P(1)。
当k=1时,有多项式P(n)=an+b。
P(n+1)=a(n+1)+b=an+a+b。
公差P(n+1)-P(n)=a。
当首项P(1)是D的倍数而且公差P(n+1)-P(n)也是D的倍数时,就ok。
为了验证首项P(1)是D的倍数,n取1。
为了验证公差P(n+1)-P(n)=a是D的倍数,这就是k=0的情况,n取1。
所以需要验证P(1),P(2)-P(1)。
即验证P(1),P(2)。
当k=2时,有多项式P(n)=an^2+bn+c。
P(n+1)=a(n+1)^2+b(n+1)+c=an^2+(2a+b)n+a+b+c。
公差P(n+1)-P(n)=2an+a+b。
要验证首项P(1)。
要验证公差P(n+1)-P(n)是D的倍数,就要验证2an+a+b是D的倍数,这就是k=1的情况,n取1,2。
所以要验证P(1),P(2)-P(1),P(3)-P(2)。
即验证P(1),P(2),P(3)。
对于k次多项式,相邻两项之差P(n+1)-P(n)是关于n的k-1次多项式。根据数学归纳法,只需验证P(i),1<=i<=k+1。
其中dP(n)=P(n+1)-P(n)叫做P(n)的差分数列。差分数列的差分数列为二阶差分数列d^2P(n)。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mp(ll x,ll n,ll mod)
{
ll ret=1;
while(n)
{
if(n&1) ret=ret*x%mod;
x=x*x%mod;
n>>=1;
}
return ret;
}
ll cul(ll C,ll n,ll E,ll mod)
{
return C%mod*mp(n,E,mod)%mod;
}
ll tot;
ll C[110];
ll E[110];
char str[100010];
bool ok()
{
ll k=1;
ll c,e;
while(str[k]!='/')
{
while(str[k]=='+') k++;
if(str[k]=='n') c=1;
else
{
if(str[k]=='-'&&str[k+1]=='n') c=-1,k++;
else
{
bool fu=false;
if(str[k]=='-') fu=true,k++;
c=0;
while(str[k]!='n'&&str[k]!=')') c=c*10+str[k++]-'0';
if(fu) c=-c;
}
}
if(str[k]==')') e=0,k++;
else if(str[k+1]!='^') e=1,k++;
else
{
k+=2;
e=0;
while(str[k]>='0'&&str[k]<='9') e=e*10+str[k]-'0',k++;
}
if(str[k]==')') k++;
C[tot]=c;
E[tot++]=e;
}
/*for(ll i=0;i<tot;i++)
printf("%lld,%lld\n",C[i],E[i]);*/
k++;
ll mod=0;
while(str[k]) mod=mod*10+str[k++]-'0';
for(k=1;k<=E[0]+1;k++)
{
ll ans=0;
for(ll i=0;i<tot;i++)
ans=(ans+cul(C[i],k,E[i],mod))%mod;
if(ans) return false;
}
gets(str);
return true;
}
int main()
{
ll kase=0;
while(scanf("%s",str),str[0]!='.')
{
tot=0;
if(ok()) printf("Case %lld: Always an integer\n",++kase);
else printf("Case %lld: Not always an integer\n",++kase);
}
return 0;
}