CF1155 E.Guess the Root

题目链接:Click here

题目大意:现在有一个至多11项的多项式\(F(x)\),你可以询问至多50个\(x\),黑盒子会告诉你\(F(x)\)的值,你现在要找到一个\(x\)使得\(F(x)=0\)

Solution:

考虑拉格朗日插值多项式的式子:
\[ F(x)=\sum_{i=0}^n(\prod_{0\le j\le n,i\not =j}\frac{x-x_i}{x_i-x_j})y_i \]
因为至多11项,所以我们询问11次即可得到这个多项式

由于\(x<1e6+3\),得到多项式后我们暴力枚举\(x\)计算\(F(x)\)即可

Code:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=1e6+3;
int p[11];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int qpow(int a,int b){
    int re=1;
    while(b){
        if(b&1) re=(re*1ll*a)%mod;
        b>>=1;a=(a*1ll*a)%mod;
    }return re%mod;
}
int query(int x){
    printf("? %d\n",x);fflush(stdout);
    int val=read();return val;
}
void write(int x){
    printf("! %d\n",x);fflush(stdout);
    exit(0);
}
signed main(){
    for(int i=0;i<=10;i++){
        p[i]=query(i);
        if(p[i]==0) write(i);
    }
    for(int i=0;i<=10;i++){
        int v=1;
        for(int j=0;j<=10;j++){
            if(i==j) continue;
            v=((i-j+mod)%mod*1ll*v)%mod;
        }
        p[i]=(p[i]*1ll*qpow(v,mod-2))%mod;
    }
    for(int i=11;i<mod;i++){
        int v=0;
        for(int j=0;j<=10;j++){
            int val=1;
            for(int k=0;k<=10;k++){
                if(j==k) continue;
                val=((i-k+mod)%mod*1ll*val)%mod;
            }val=(val*1ll*p[j])%mod;
            v=(v+val)%mod;
        }
        if(!v) write(i);
    }write(-1);
    return 0;
}
上一篇:Java猜数字游戏控制台版GuessNumberConsole


下一篇:剑指offer 斐波那契数列