数学题(总是整数,LA 4119)

判断一个关于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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值