http://acm.hdu.edu.cn/showproblem.php?pid=4569php
首先若是f(x)%(p*p)=0,則必有f(x)%p=0,所以解x必然在知足f(x)%p=0的集合中。ios
接着注意到p爲質數,f(x)爲多項式,那麼知足f(x)%p=0的集合在p的剩餘系中必然不多,而因爲f(x)爲多項式,那麼根據同餘模定理,必然有f(x+k*p*p)=f(x) (mod p*p)。所以找到知足f(x)%p=0的集合x(x在p的剩餘系中),而後枚舉k便可。ide
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<math.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1e9+10; int n; ll a[maxn],p; ll qpow(ll n,ll k,ll p) { ll res=1; while(k){ if(k&1) res=(res*n)%p; n=(n*n)%p; k>>=1; } return res; } ll f(ll x,ll p) { ll res=0; REP(i,0,n){ res=(res+a[i]*qpow(x,i,p))%p; } return res; } int main() { freopen("in.txt","r",stdin); int T;cin>>T;int casen=1; while(T--){ scanf("%d",&n); for(int i=n;i>=0;i--) scanf("%I64d",&a[i]); scanf("%I64d",&p); REP(i,0,n){ while(a[i]<0) a[i]+=p*p*100000; a[i]%=p*p; } bool flag=0; ll ans=-1; REP(x,0,p-1){ if(f(x,p)==0){ for(ll y=x;y<p*p;y+=p){ if(f(y,p*p)==0){ ans=y;flag=1; } if(flag) break; } } if(flag) break; } printf("Case #%d: ",casen++); if(flag) printf("%I64d\n",ans); else puts("No solution!"); } return 0; }
唉,我怎麼那麼笨,連這都沒看出來。。spa
總結,若是對於f(x)=y(mod p) ,若是f(x)爲多項式,那麼就應該善於用同餘模定理,若是找解的話,能夠考慮枚舉,但要注意枚舉的範圍,不要去枚舉那些明顯不在解集中的數。code