码迷,mamicode.com
首页 > 其他好文 > 详细

E - Guess the Root 拉格朗日差值法+交互

时间:2019-04-23 21:22:09      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:题意   set   limits   ace   scanf   amp   jci   clr   div   

题目传送门

  题意:告诉你存在一个未知项系数最高为10的$f(x)$,你最多可以有50次询问,每次询问给出一个$x‘$,系统会返回你$f(x‘)$的值,你需要猜一个$x‘‘$,使得$f(x‘‘)=0$,所有运算都是取模1e6+3下进行的。

  思路:拉格朗日插值法的模板题。yyb聚聚的公式

  $p(x)=\sum\limits_{n}^{i=0}(-1)n-i*p(i)*x*(x-1)*(x-2)*(x-3)*……*(x-n)/((n-i)! * i! * (x-i))$

       所以先暴力询问0-10的所有答案,然后判断11-p的答案是否为0即可。

#include<bits/stdc++.h>
#define CLR(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const ll p=1e6+3;
ll a[11],f[20],jcinv[20],inv[p+2];
ll qpow(ll a,ll b){
    ll res=1;
    a%=p;
    while(b){
        if(b&1)res=res*a%p;
        b>>=1;
        a=a*a%p;
    }
    return res;
}
void init(){
    f[0]=1;
    for(int i=1;i<=13;i++)f[i]=f[i-1]*i%p;
    jcinv[13]=qpow(f[13],p-2);
    for(int i=13;i>0;i--){
        jcinv[i-1]=jcinv[i]*i%p;
    }
    inv[1]=1;
    for(int i=2;i<=p;i++)
    {
        inv[i]=inv[p%i]*(p-p/i)%p;
    }
}
int main(){
    init();
    for(int i=0;i<=10;i++)
    {
        printf("? %d\n",i);
        fflush(stdout);
        scanf("%lld",&a[i]);
        if(a[i]==0){
            printf("! %d\n",i);
            fflush(stdout);
            return 0;
        }
    }
    for(int k=11;k<p;k++)
    {
        ll up=1;
        for(int i=0;i<=10;i++)up=up*(k-i)%p;
        ll res=0;
        for(int i=0;i<=10;i++)
        {
            ll tep=0;
            tep=a[i]*up%p*jcinv[10-i]%p*jcinv[i]%p*inv[k-i]%p;
            res=(res+tep*(i%2==0?1:-1)+p)%p;
        }
        if(res==0){
            printf("! %d\n",k);
            fflush(stdout);
            return 0;
        }
    }
    printf("! -1\n");
    fflush(stdout);
}

 

E - Guess the Root 拉格朗日差值法+交互

标签:题意   set   limits   ace   scanf   amp   jci   clr   div   

原文地址:https://www.cnblogs.com/mountaink/p/10758670.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!