题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4569
题目意思:
给一个不超过四次的一元多项式,求一个x使得该多项式的值mod给定质数p的平方为0.
解题思路:
设给定的多项式为f(x)=a4*x^4+a3*x^3+a2*x^2+a1*x+a0
显然f(x+p^2)=f(x)mod(p^2).故只需讨论0~p^2范围内(其他数如果满足,一定可以转化到该范围内)是否存在满足题意的。
如果直接o(p^2)的话肯定会超时,所以需要剪枝。
因为p为质数,并且f(x+p)=f(x) mod p,如果f(x)=0 mod p^2 必定有f(x)=0 mod p ,但如果连f(x)=0 mod p都不成立的话,肯定不满足f(x)=0 mod p^2 所以这里这个剪枝效果很大。
所以先把0~p内满足f(x)= 0 mod p的x找到,再判断x,x+p,x+2p,,..x+np <p*p (这些数都满足f(x)=0 mod p) 是否满足f(x)=0 mod p^2 即可。
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
/*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/
ll xi[10],n;
ll Cal(ll x,ll p) //计算f(x)%p
{
ll res=0,tmp=1;
for(int i=0;i<=n;i++)
{
res=(res+xi[i]*tmp)%p;
tmp=(tmp*x)%p;
}
return (res+p)%p;
}
int main()
{
int t;
scanf("%d",&t);
for(int ca=1;ca<=t;ca++)
{
scanf("%I64d",&n);
for(int i=n;i>=0;i--)
scanf("%I64d",&xi[i]);
ll p;
scanf("%I64d",&p);
int lim=p*p;
bool flag=false;
printf("Case #%d: ",ca);
for(ll i=0;i<p;i++) //现在0~p范围内找 f(x)%p=0的x
{
ll tmp=Cal(i,p);
if(tmp%p==0) //再判断 f(x+k*P)是否能被p^2整除
{
//printf("ldjdkj\n");
int sum=i;
while(sum<lim)
{
int tt=Cal(sum,lim);
if(!tt)
{
flag=true;
printf("%d\n",sum); //找到了,直接输出
break;
}
sum+=p;
}
if(flag)
break;
}
}
if(!flag)
printf("No solution!\n");
}
return 0;
}