Educational Codeforces Round 63 (Rated for Div. 2) E 带模高斯消元

https://codeforces.com/contest/1155/problem/E

题意

\(f(x)=a_0+a_1x+a_2x^2+...+a_kx^k,k \leq 10,0 \leq a_i < 10^6+3\),每次可以询问一个x,返回\(f(x)mod(10^6+3)\),50次询问以内需要找到x使得 \(f(x) \equiv 0 mod(10^6+3)\)

题解

  • 现未知\(a_0,a_1,...,a_k\),一共k+1个未知数,需要k+1个方程来解,因此只需要询问k+1次即可
  • 将x看成系数,\(a_0,a_1,...,a_k\)当成未知数,带模高斯消元即可

代码

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const ll P=1e6+3;
ll a[15][15],b[15];

int ask(int i){
    printf("? %d\n",i);
    fflush(stdout);
    int x;scanf("%d",&x);
    return x;
}
ll inv(ll bs){
    ll ans=1,x=P-2;
    while(x){
        if(x&1)ans=ans*bs%P;
        bs=bs*bs%P;
        x>>=1;
    }
    return ans;
}
void gao(){
    for(int i=0;i<=10;i++){
        for(int j=i+1;j<=10;j++){
            ll rate=a[j][i]*inv(a[i][i])%P;
            for(int k=i;k<=11;k++){
                a[j][k]-=a[i][k]*rate%P;
                a[j][k]+=P;a[j][k]%=P;
            }
        }
    }
    for(int i=10;i>=0;i--){
        for(int j=i-1;j>=0;j--){
            ll rate=a[j][i]*inv(a[i][i])%P;
            a[j][11]-=a[i][11]*rate%P;
            a[j][11]+=P;a[j][11]%=P;
        }
        a[i][i]=a[i][11]*inv(a[i][i])%P;
    }
}

int chk(ll x){
    b[0]=1;
    for(int i=1;i<=10;i++)b[i]=b[i-1]*x%P;
    ll sum=0;
    for(int i=0;i<=10;i++){
        sum+=b[i]*a[i][i]%P;
        sum%=P;
    }
    return sum==0;
}
int main(){
    for(int i=0;i<=10;i++){
        a[i][11]=ask(i);
        ll p=1;
        for(int j=0;j<=10;j++){
            a[i][j]=p;
            p=p*i%P;
        }
    }
    gao();
    for(int i=0;i<P;i++){
        if(chk(i)){
            printf("! %d\n",i);
            fflush(stdout);
            return 0;
        }
    }
    printf("! -1\n");fflush(stdout);
}

猜你喜欢

转载自www.cnblogs.com/VIrtu0s0/p/10812442.html