https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3510
如果 f ( x ) , x ∈ N + f(x), x\in N_+ f(x),x∈N+是 D D D的倍数,那么可以等价为 f ( 1 ) f(1) f(1)为 D D D的倍数且 f ( x + 1 ) − f ( x ) , x ∈ N + f(x+1)-f(x),x\in N_+ f(x+1)−f(x),x∈N+为 D D D的倍数
假设多项式的最高次数为 k k k,当 k = 0 k=0 k=0时只需要验证常数项是不是 D D D的倍数
当 k = 1 k=1 k=1时,该式可以写成 f ( x ) = k x + b f(x)=kx+b f(x)=kx+b,只需要验证 f ( 1 ) , f ( 2 ) − f ( 1 ) f(1),f(2)-f(1) f(1),f(2)−f(1)是不是 D D D的倍数,即验证 f ( 1 ) , f ( 2 ) f(1),f(2) f(1),f(2)是不是 D D D的倍数
当 k = 2 k=2 k=2时,需要验证 f ( 1 ) f(1) f(1)和 f ( n + 1 ) − f ( n ) f(n+1)-f(n) f(n+1)−f(n)是不是 D D D的倍数,假设 f ( 1 ) f(1) f(1)是 D D D的倍数,那么只需要验证 f ( 2 ) − f ( 1 ) , f ( 3 ) − f ( 2 ) , f ( 4 ) − f ( 3 ) . . . . . . f(2)-f(1),f(3)-f(2),f(4)-f(3)...... f(2)−f(1),f(3)−f(2),f(4)−f(3)......是不是 D D D的倍数,即验证 f ( 2 ) , f ( 3 ) , f ( 4 ) . . . f ( n ) , n ≥ 2 f(2),f(3),f(4)...f(n),n\geq 2 f(2),f(3),f(4)...f(n),n≥2是不是 D D D的倍数,那么这又回到了 k = 1 k=1 k=1的子问题,只需要验证前两项 f ( 2 ) , f ( 3 ) f(2),f(3) f(2),f(3)即可
当 k = 3 k=3 k=3时,验证完 f ( 1 ) f(1) f(1)是 D D D的倍数后,同样会回到 k = 2 k=2 k=2的子问题,最终仅需验证 f ( 1 ) , f ( 2 ) , f ( 3 ) , f ( 4 ) f(1),f(2),f(3),f(4) f(1),f(2),f(3),f(4)
所以最后发现我只需要验证 f ( 1 ) , f ( 2 ) , . . . , f ( k + 1 ) f(1),f(2),...,f(k+1) f(1),f(2),...,f(k+1)即可
//数学题
#include
#define ll long long
#define maxn 110
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
ll c[maxn], e[maxn], tot, D;
ll fastpow(ll a, ll b)
{
ll t=a, ans=1;
for(;b;b>>=1,t=t*t%D)if(b&1)ans=ans*t%D;
return ans;
}
bool init()
{
cl(c), cl(e), tot=0;
char s[100000];
ll i, j, k, p, x, f;
scanf("%s",s+1);
if(s[1]=='.')return false;
if(s[2]!='-')s[1]='+';
p=1;
while(1)
{
for(;s[p]!='+' and s[p]!='-' and s[p]!=')';p++);
for(x=0,i=p+1;isdigit(s[i]);i++)x=(x<<1)+(x<<3)+s[i]-48;
if(s[i]==')')
{
c[++tot]=x;
e[tot]=0;
p=i;
break;
}
tot++;
f=s[p]=='-'?-1:1;
if(!x)x=1;
c[tot]=f*x;
p=i+1;
if(s[p]=='^')
{
for(i=p,x=0;isdigit(s[i+1]);i++)x=(x<<1)+(x<<3)+s[i+1]-48;
e[tot]=x;
p=i+1;
}
else e[tot]=1;
if(s[p]==')')break;
}
for(;!isdigit(s[p]);p++);
for(D=0;isdigit(s[p]);p++)D=(D<<1)+(D<<3)+s[p]-48;
return true;
}
ll f(ll x)
{
ll i, ans=0;
for(i=1;i<=tot;i++)ans=(ans+c[i]*fastpow(x,e[i]))%D;
return (ans+D)%D;
}
bool judge()
{
ll i, j, k=e[1];
for(i=1;i<=k+1;i++)if(f(i))return false;
return true;
}
int main()
{
ll i, j, kase=0;
while(init())
{
printf("Case %lld: ",++kase);
if(judge())printf("Always an integer\n");
else printf("Not always an integer\n");
}
return 0;
}