链接
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 <bits/stdc++.h>
#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;
}