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;
}
posted @ 2023-12-07 16:39  5k_sync_closer  阅读(1)  评论(0编辑  收藏  举报  来源