Educational Codeforces Round 63 E.Guess the Root

链接

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

题解

我是这样做的,询问 f ( 1 ) , f ( 2 ) , f ( 4 ) , . . . f ( 10 ) f(1),f(2),f(4),...f(10) f(1),f(2),f(4),...f(10)得到10个方程
容易发现,这样构造出来的方程一定可以解出每个系数
高斯消元解一下,最后枚举根即可

代码

#include <bits/stdc++.h>
#define maxn 15
#define eps 1e-8
#define linf (1ll<<60)
#define cl(x) memset(x,0,sizeof(x))
#define mod 1000003ll
using namespace std;
typedef long long ll;
ll c[maxn], K=10;
ll read(ll x=0)
{
    ll c, f=1;
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-48;
    return f*x;
}
ll fastpow(ll a, ll b)
{
	ll t(a), ans(1);
	for(;b;b>>=1,t=t*t%mod)if(b&1)ans=ans*t%mod;
	return ans;
}
ll inv(ll x)
{
	return fastpow(x,mod-2);
}
struct matrix
{
    ll n, m;
    ll a[maxn][maxn];
    matrix(ll n, ll m):n(n),m(m){cl(a);}
    ll* operator[](const ll& index){return a[index];}
    void gauss()
    {
        ll i, j, k, r;
        for(i=1;i<=n;i++)
        {
            r=i;
            for(j=r+1;j<=n;j++)if(a[j][i])r=j;
            for(j=1;j<=n+1;j++)swap(a[i][j],a[r][j]);
			ll t=inv(a[i][i]);
            for(j=1;j<=n;j++)if(j!=i)
            {
				for(k=n+1;k>=i;k--)
				{
					a[j][k] = ( a[j][k] - a[j][i]*t%mod*a[i][k] ) % mod;
					a[j][k] = (a[j][k]%mod+mod)%mod;
				}
            }
        }
    }
    void show()
    {
        for(ll i=1;i<=n;i++)for(ll j=1;j<=n+1;j++)printf("%2lld",a[i][j]), putchar(j==n+1?10:32);
    }
};
ll mi[10000];
bool check(ll x)
{
	ll f=0, i, t=1;
	for(i=1;i<=11;i++)
	{
		f+=t*c[i];
		f%=mod;
		t=t*x%mod;
	}
	return f==0ll;
}
int main()
{
	ll i, x, j, res=50;
	matrix T(11,12);
	mi[0]=1;
	for(i=1;i<=5000;i++)mi[i]=mi[i-1]*2%mod;
	for(i=1;i<=11;i++)
	{
		cout<<"? "<<mi[i-1]<<endl;
		res--;
		cin>>x;
		for(j=1;j<=11;j++)
		{
			T[i][j] = mi[(j-1)*(i-1)];
		}
		T[i][12] = x%mod;
	}
	T.gauss();
	for(i=1;i<=11;i++)c[i]=T[i][12]*inv(T[i][i])%mod;
	for(i=0;i<mod and res;i++)
	{
		if(check(i))
		{
			cout<<"? "<<i<<endl;
			cin>>x;
			res--;
			if(x==0)
			{
				cout<<"! "<<i<<endl;
				return 0;
			}
		}
	}
	cout<<"! -1"<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值