CF1155E Guess the Root 题解
通过拉格朗日插值,确定一个 $10$ 次多项式只需要 $11$ 个点值,也就是只需要 $11$ 次询问。
多项式的值是模 $10^6+3$ 意义下的,所以有零点时 $[0,10^6+3)$ 内必有一个零点,枚举这个范围即可。
#include <cstdio>
#define M 1000003
#define int long long
int f[20], o[M + 50], v[M + 50];
int F(int x)
{
if (x <= 10)
return f[x];
int z = 1, q = 0;
for (int i = 0; i <= 10; ++i)
z = z * (x - i) % M;
for (int i = 0, k; i <= 10; ++i)
k = f[i] * v[x - i] % M * v[o[i]] % M * v[o[10 - i]] % M, q = 10 - i & 1 ? (q + M - k) % M : (q + k) % M;
return q * z % M;
}
signed main()
{
for (int i = o[0] = 1; i <= M; ++i)
o[i] = o[i - 1] * i % M;
v[1] = 1;
for (int i = 2; i < M; ++i)
v[i] = (M - M / i) * v[M % i] % M;
for (int i = 0; i <= 10; ++i)
{
printf("? %lld\n", i);
fflush(stdout);
scanf("%lld", f + i);
}
for (int i = 0; i < M; ++i)
if (!F(i))
{
printf("! %lld\n", i);
fflush(stdout);
return 0;
}
puts("! -1");
fflush(stdout);
return 0;
}