Special equations
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 189 Accepted Submission(s): 97
Special Judge
Problem Description
Let f(x) = a
nx
n +...+ a
1x +a
0, in which a
i (0 <= i <= n) are all known integers. We call f(x) 0 (mod m) congruence equation. If m is a composite, we can factor m into powers of primes and solve every such single equation after which we merge them using the Chinese Reminder Theorem. In this problem, you are asked to solve a much simpler version of such equations, with m to be prime's square.
Input
The first line is the number of equations T, T<=50.
Then comes T lines, each line starts with an integer deg (1<=deg<=4), meaning that f(x)'s degree is deg. Then follows deg integers, representing a
n to a
0 (0 < abs(a
n) <= 100; abs(a
i) <= 10000 when deg >= 3, otherwise abs(a
i) <= 100000000, i<n). The last integer is prime pri (pri<=10000).
Remember, your task is to solve f(x) 0 (mod pri*pri)
Output
For each equation f(x) 0 (mod pri*pri), first output the case number, then output anyone of x if there are many x fitting the equation, else output "No solution!"
Sample Input
4
2 1 1 -5 7
1 5 -2995 9929
2 1 -96255532 8930 9811
4 14 5458 7754 4946 -2210 9601
Sample Output
Case #1: No solution!
Case #2: 599
Case #3: 96255626
Case #4: No solution!
Source
2013 ACM-ICPC长沙赛区全国邀请赛——题目重现
思路:
如果满足f(x)%(p*p)=0必须要满足f(x)%p=0这个条件,如果f(x)%p=0,那么f(x-p)%prime=0。所以只需要在0~p-1的范围内枚举x就够了。如果满足f(x)%p=0,则验证是否满足f(x)%(p*p)=0。第二重循环验证的时候每次只需要j+=p就够了(能够保证f(x)%p=0),不要j++,因为如果j++满足f(x)%p=0的话也会在第一重循环时枚举到。
ps:当时队友莫莫已经想到这里了,给我们提了一下,我们没多思考,没多加验证,所以白白浪费了这么好的一题呀!
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 105
using namespace std;
int n,m,ans,p,pp;
int a[maxn];
long long calf(int k)
{
int i,j,cnt;
long long s=0,t;
for(i=0;i<=n;i++)
{
cnt=n-i;
t=1;
while(cnt--)
{
t*=k;
}
t*=a[i];
s+=t;
}
return s;
}
bool solve()
{
int i,j;
pp=p*p;
long long s;
for(i=0;i<p;i++) // 必要条件缩小范围
{
s=calf(i);
if(s%p==0)
{
if(s%pp==0)
{
ans=i;
return true ;
}
for(j=i+p;j<=pp;j+=p)
{
if(calf(j)%pp==0)
{
ans=j;
return true ;
}
}
}
}
return false ;
}
int main()
{
int i,j,k,t;
scanf("%d",&t);
for(k=1;k<=t;k++)
{
scanf("%d",&n);
for(i=0;i<=n;i++)
{
scanf("%d",&a[i]);
}
scanf("%d",&p);
printf("Case #%d: ",k);
if(solve()) printf("%d\n",ans);
else printf("No solution!\n");
}
return 0;
}