• 题解 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;
    }
    
  • 相关阅读:
    基于差分隐私的安全机制
    基于散列和RSA的纵向联邦学习样本对齐实现方案
    富文本及编辑器的跨平台方案
    计算机字符编码的前世今生
    探究Presto SQL引擎(1)-巧用Antlr
    vivo 全球商城:优惠券系统架构设计与实践
    复杂多变场景下的Groovy脚本引擎实战
    分布式存储系统可靠性:系统量化估算
    手把手教你实现Android编译期注解
    灵活运用分布式锁解决数据重复插入问题
  • 原文地址:https://www.cnblogs.com/colazcy/p/14110842.html
Copyright © 2020-2023  润新知