zoukankan      html  css  js  c++  java
  • [BZOJ2742][HEOI2012]Akai的数学作业[推导]

    题意

    给定各项系数,求一元 (n) 次方程的有理数解。

    (nleq 100)

    分析

    • 设答案为 (frac{p}{q}) ,那么多项式可以写成 (a_0frac{p}{q}+a_1frac{p^2}{q^2}+cdots a_nfrac{p^n}{q^n}) 的形式。

    • 左右乘以 (q^n) :得到:(sum_{i=0}^n {a_ip^iq^{n-i}}=0)

    • 可以推出

      • (a_0q^n=p*A) ;
      • (a_np^n=q*B) ;
    • 因为 (p,q) 互质,所以得到 (a_0) 必为 (p) 倍数, (a_n) 必为 (q) 倍数。

    • 因为最低项可能为 (0),所以以第一个不为 (0) 的项作为基准,结论是一致的。

    • 可以通过对几个大质数取模的方式判断是否为 (0)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define pb push_back
    typedef long long LL;
    inline int gi(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch))	{if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    	return x*f;
    }
    template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
    template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
    const int N=107;
    int n,mod,cnt;
    int a[N],bp[N],bq[N];
    int M[]={19260817,998244353,1000000007,19491001,48271};
    vector<int>v0,vn;
    void add(int &a,int b){a+=b;if(a>=mod) a-=mod;}
    bool check(int p,int q){
    	for(int j=0;j<5;++j){
    		mod=M[j];int tmp=0;
    		bp[0]=bq[0]=1;
    		for(int i=1;i<=n;++i) bp[i]=1ll*bp[i-1]*p%mod,bq[i]=1ll*bq[i-1]*q%mod;
    		rep(i,0,n) add(tmp,(1ll*a[i]*bp[i]%mod*bq[n-i]%mod+mod)%mod);
    		if(tmp) return 0;
    	}
    	return 1;
    }
    int gcd(int a,int b){
    	return !b?a:gcd(b,a%b);	
    }
    struct fs{
    	int fz,fm;
    	bool operator <(const fs &b)const{
    		return 1ll*fz*b.fm<1ll*b.fz*fm;	
    	}
    	bool operator !=(const fs &b)const{
    		return fz!=b.fz||fm!=b.fm;	
    	}
    };
    vector<fs>ans;
    int main(){
    	n=gi();
    	rep(i,0,n) a[i]=gi();
    	
    	int x=0;
    	while(!a[x]) ++x;
    	if(x) v0.pb(0);
    	x=abs(a[x]);
    	for(int i=1,l=(int)sqrt(x);i<=l;++i)if(x%i==0){
    		v0.pb(i),v0.pb(-i);
    		if(i*i!=x) v0.pb(x/i),v0.pb(-x/i);
    	}
    	
    	x=abs(a[n]);
    	for(int i=1,l=(int)sqrt(x);i<=l;++i)if(x%i==0){
    		vn.pb(i);
    		if(i*i!=x) vn.pb(x/i);
    	}
    	for(auto p:v0)
    	for(auto q:vn){
    		int x=p,y=q;
    		if(check(x,y)){
    			int g=gcd(x,y);
    			x/=g,y/=g;
    			ans.pb((fs){x,y});
    		}
    	}
    	
    	sort(ans.begin(),ans.end());
    	for(int i=0;i<ans.size();++i)
    		if(i==0||ans[i]!=ans[i-1]) ++cnt;
    	printf("%d
    ",cnt);
    	
    	for(int i=0;i<ans.size();++i)
    	if(i==0||ans[i]!=ans[i-1]){
    		if(ans[i].fm!=1) printf("%d/%d
    ",ans[i].fz,ans[i].fm);
    		else printf("%d
    ",ans[i].fz);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Vue之常用语法
    Django之crm
    Django项目之客户
    前端、数据库、Django简单的练习
    Django的认证系统
    Django之form表单
    OpneCV 二值图像区域处理
    OpenCV图像处理中常用函数汇总(1)
    OpenCV3编程入门笔记(6)自我验证各函数程序代码
    OpenCV_轮廓的查找、表达、绘制、特性及匹配
  • 原文地址:https://www.cnblogs.com/yqgAKIOI/p/9814710.html
Copyright © 2011-2022 走看看