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; //记得无解
}
}

浙公网安备 33010602011771号