CF1155E 题解

题意:

交互题,界为十的多项式,最多得到 \(50\)\(x\) 取值下 \(y\) 的取值,求原多项式的零点。模 \(1\times10^6+3\) 意义下。

思路:

考虑如果知道了原多项式,可以枚举模意义下每个可能的取值判断,模数较小,可以通过。

因此问题转化成了如何求解原多项式,设原多项式为 \(\sum_{i=0}^na_i\times x^i\) 其中 \(n\) 为多项式的界。
对于每个询问 \(x_j\),设 \(f_{j,i}\) 表示 \((x_j)^i\)。我们就可以得到 \(\sum_{i=0}^nf_{j,i}\times a_i\)

很明显我们是知道 \(f\) 的(你问的你不知道)。发现这个形式就可以高斯消元做了,只需要问至少 \(11\) 次(包括常数项),得到 \(n\)\(n\)\(1\) 次方程,联立解掉就行了。

最后这题是模意义下的,记得求逆元。

#include<bits/stdc++.h>
#define int long long 
using namespace std;
const int mod = 1e6 + 3;
int a[21][21], b[231], n = 11;
inline int qpow(int a, int b){
    int res = 1; while(b){
        if(b & 1) res = res * a % mod;
        a = a * a % mod; b >>= 1;
    } return res; //逆元
}
inline int f(int x){
    int res = 0;
    for(int i = 1, j = 1; i <= 11; i++)
        (res += b[i] * j) %= mod, j = j * x % mod;
    return res;
}
signed main(){
    for(int i = 1, x; i <= n; i++){
        cout << "? " << i << endl;
        cin >> x; a[i][12] = x;
        for(int j = 1, k = 1; j <= 11; j++)
            a[i][j] = k, k = k * i % mod;
    }// 询问11次
    for(int i = 1; i <= n; i++){
        for(int j = i; j <= n; j++) if(a[j][i]) {swap(a[i], a[j]); break;}
        for(int j = 1; j <= n; j++){ if(i == j) continue;
            int d = (-a[j][i]*qpow(a[i][i],mod-2)%mod+mod)%mod;
            for(int k = 1; k <= 12; k++) (a[j][k]+=a[i][k]*d%mod)%mod;
        }
    } //高斯消元
    for(int i = 1; i <= n; i++) b[i] = a[i][12] * qpow(a[i][i], mod - 2) % mod;
    for(int i = 0; i < mod; i++)
        if(f(i) == 0) return cout << "! " << i << endl, 0; //枚举答案
    cout << "! -1" << endl; //记得无解
}
}
posted @ 2023-10-04 23:38  xlpg0713  阅读(19)  评论(0)    收藏  举报