UVA1069 Always an integer

链接

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),xN+ 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),xN+ 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),n2是不是 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值