zoukankan      html  css  js  c++  java
  • 题解 CF1155E 【Guess the Root】

    题目链接

    Solution CF1155E Guess the Root

    题目大意:有一个次数不超过 (10) 的多项式,你可以询问该多项式在 (x) 处的值,询问次数限制 (50) 次。求该多项式的零点(运算在模 (1e6+3) 意义下进行)

    交互、高斯消元


    分析:

    首先模数与次数都较小,所以求零点我们可以直接暴力,那么我们就要想办法把这个多项式给找出来。

    (n + 1) 个点可以确定一个 (n) 次多项式(假设待定系数法搞出来的矩阵是满秩的),所以我们直接随机 (50) 个点,高斯消元然后暴力即可

    也可以拉格朗日插值

    #include <cstdio>
    #include <random>
    #include <chrono>
    #include <cstdlib>
    using namespace std;
    constexpr int maxn = 64,mod = 1e6 + 3,qtot = 50;
    constexpr inline int add(const int a,const int b){return (a + b) % mod;}
    constexpr inline int mul(const int a,const int b){return (1ll * a * b) % mod;}
    constexpr inline int sub(const int a,const int b){return (a - b + mod) % mod;}
    inline int qpow(int base,int b){
    	int res = 1;
    	while(b){
    		if(b & 1)res = mul(res,base);
    		base = mul(base,base);
    		b >>= 1;
    	}
    	return res;
    }
    inline int inv(const int x){return qpow(x,mod - 2);}
    inline int calc(const int a,const int b){return mul(a,inv(b));}
    mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
    
    int ques[maxn],mat[maxn][maxn],a[maxn];
    inline int query(const int x){
    	int res;
    	printf("? %d
    ",x);fflush(stdout);
    	scanf("%d",&res);
    	return res;
    }
    int mem[maxn][maxn];
    inline void query(){
    	for(int k = 0;k < qtot;k++){
    		const int x = ques[k];
    		mat[k][11] = query(x);
    		for(int i = 0;i <= 10;i++)mat[k][i] = qpow(x,i);
    	}
    }
    inline void gauss(){
    	const int n = qtot - 1;
    	const int m = 10;
    	for(int i = 0;i <= m;i++){
    		int r = -1;
    		for(int j = i;j <= n;j++)
    			if(mat[j][i])r = j;
    		if(r == -1)exit(-1);
    		swap(mat[i],mat[r]);
    		for(int j = i + 1;j <= n;j++){
    			const int k = calc(mat[j][i],mat[i][i]);
    			for(int l = i;l <= m + 1;l++)mat[j][l] = sub(mat[j][l],mul(mat[i][l],k));
    		}
    	}
    	for(int i = m;i >= 0;i--){
    		a[i] = mat[i][m + 1];
    		for(int l = i + 1;l <= m;l++)a[i] = sub(a[i],mul(mat[i][l],a[l]));
    		a[i] = calc(a[i],mat[i][i]);
    	}
    }
    
    inline int calc(int x){
    	int res = 0;
    	for(int i = 0;i <= 10;i++)res = add(res,mul(a[i],qpow(x,i)));
    	return res;
    }
    inline void solve(){
    	for(int i = 0;i < mod;i++)
    		if(!calc(i)){
    			printf("! %d
    ",i);
    			return;
    		}
    	puts("! -1");
    }
    int main(){
    	for(int i = 0;i < qtot;i++)ques[i] = rnd() % mod;
    	query();
    	gauss();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    设计模式——创建型设计模式总结(简单工厂、普通工厂、抽象工厂、建造者、原型和单例)
    网易游戏2011招聘笔试题+答案解析
    华为2011上机笔试题2+参考程序
    趋势科技2011校招笔试题+答案解析
    腾讯2012实习生笔试题2+答案解析
    浙商银行2011笔试题+答案解析
    Linux学习笔记(三)——权限管理
    PowerShell在多个文件中检索关键字
    Linux学习笔记(一)——入门
    PowerShell函数调用问题
  • 原文地址:https://www.cnblogs.com/colazcy/p/14110842.html
Copyright © 2011-2022 走看看