• BZOJ 2742: [HEOI2012]Akai的数学作业


    2742: [HEOI2012]Akai的数学作业

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 572  Solved: 236
    [Submit][Status][Discuss]

    Description

     
    这里是广袤无垠的宇宙这里是一泻千里的银河
    这里是独一无二的太阳系
    这里是蔚蓝色的地球
    这里,就是这里,是富饶的中国大陆!
    这里是神奇的河北大地
    这里是美丽的唐山
    这里是神话般的唐山一中
    这里是Akai曾经的教室
    黑板上还留有当年Akai做过的数学作业,其实也并不是什么很困难的题目:
    给出一个一元n次方程:
    a0 + a1x + a    2   x2 +…+ anxn= 0
    求此方程的所有有理数解。
     ” Akai至今还深刻记得当年熬夜奋战求解的时光
    他甚至还能记得浪费了多少草稿纸
    但是却怎么也想不起来最后的答案是多少了
    你能帮助他么?

    Input

    第一行一个整数n。第二行n+1个整数,分别代表a    0 到a n

    Output

    第一行输出一个整数t,表示有理数解的个数
    接下来t行,每行表示一个解
    解以分数的形式输出,要求分子和分母互质,且分母必须是正整数特殊的,如果这个解是一个整数,那么直接把这个数输出
    等价的解只需要输出一次
    所有解按照从小到大的顺序输出

    Sample Input

    3
    -24 14 29 6

    Sample Output

    3
    -4
    -3/2
    2/3

    HINT

    【数据范围】

    对于30%的数据,n<=10 

    对于100%的数据,n <= 100,|a i| <= 2*10^7,an≠ 0

    Source

    分析:

    对于一个多项式我们可以把它写成$f(x)=prod (b_{i}x+c_{i})$的形式,每一个一次多项式都有一个复数域下的根,这道题求的是有理数解,所以可以写成$f(x)=g(x) prod (b_{i}x+c_{i})$的形式,其中$g(x)$包含了所有含非有理数解的一次多项式,那么所有的解就是$x=-frac {c_{i}}{b_{i}}$,我们观察发现,所有的$c_{i}$的乘积一定被包含在$a_0$,所有的$b_{i}$的乘积一定被包含在$a_n$,所以我们枚举$a_0$和$a_n$的约数,然后代入方程判断...

    注意有$a_0=0$的情况...这个时候就把多项式整体往前挪...

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    //by NeighThorn
    using namespace std;
    
    const int maxn=100+5,maxm=500000+5,mod=1e9+7;
    
    int n,tot,a[maxn],p[maxn],q[maxn],fac[2][maxm],cnt[2];
    
    struct M{
    	
    	int x,y;
    	
    	friend bool operator < (M a,M b){
    		return (double)a.x/(double)a.y<(double)b.x/(double)b.y;
    	}
    	
    }ans[maxm];
    
    inline int power(long long x,int y){
    	long long res=1;
    	while(y){
    		if(y&1) 
    			res=res*x%mod;
    		x=x*x%mod,y>>=1;
    	}
    	return res;
    }
    
    inline bool check(int x,int y){
    	long long ans=0;
    	for(int i=0;i<=n;i++)
    		(ans+=1LL*a[i]*power(x,i)%mod*power(y,n-i)%mod)%=mod;
    	if(ans)
    		return 1;
    	return 0;
    }
    
    inline int gcd(int x,int y){
    	return y==0?x:gcd(y,x%y);
    }
    
    signed main(void){
    	scanf("%d",&n);
    	for(int i=0;i<=n;i++)
    		scanf("%d",&a[i]);
    	int lala=0;
    	while(a[lala]==0)
    		lala++;
    	if(lala!=0){
    		for(int i=0,j=lala;j<=n;i++,j++)
    			a[i]=a[j];
    		n-=lala;
    		ans[++tot].x=0,ans[tot].y=1;
    	}
    	if(n==0){
    		puts("0");
    		return 0;
    	}
    	int xx=abs(a[0]),yy=abs(a[n]),x=sqrt(xx),y=sqrt(yy);
    	for(int i=1;i<=x;i++)
    		if(xx%i==0){
    			fac[0][++cnt[0]]=i;
    			if(i*i<=xx&&xx/i!=i)
    				fac[0][++cnt[0]]=xx/i;
    		}
    	for(int i=1;i<=y;i++)
    		if(yy%i==0){
    			fac[1][++cnt[1]]=i;
    			if(i*i<=yy&&yy/i!=i)
    				fac[1][++cnt[1]]=yy/i;
    		}
    	for(int i=1;i<=cnt[0];i++)
    		for(int j=1;j<=cnt[1];j++){
    			if(gcd(fac[0][i],fac[1][j])==1){
    				if(!check(fac[0][i],fac[1][j]))
    					ans[++tot].x=fac[0][i],ans[tot].y=fac[1][j];
    				if(!check(-fac[0][i],fac[1][j]))
    					ans[++tot].x=-fac[0][i],ans[tot].y=fac[1][j];
    			}
    		}
    	sort(ans+1,ans+tot+1);printf("%d
    ",tot);
    	for(int i=1;i<=tot;i++){
    		if(ans[i].y!=1)
    			printf("%d/%d
    ",ans[i].x,ans[i].y);
    		else
    			printf("%d
    ",ans[i].x);
    	}
    	return 0;
    }
    

      


    By NeighThorn

  • 相关阅读:
    回顾2018,展望2019
    NLog日志框架使用探究-1
    基于NetMQ的TLS框架NetMQ.Security的实现分析
    鸟哥的Linux私房菜笔记第五章,文件权限与目录配置(二)
    鸟哥的Linux私房菜笔记第五章,文件权限与目录配置(一)
    鸟哥的Linux私房菜笔记第四章
    ThinkPHP5.1 + tufanbarisyildirim 解析apk
    Java核心技术第八章——泛型程序设计(1)
    Java核心技术第五章——2.Object类
    Java核心技术第五章——1.类、超类、子类(2)
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6492173.html
Copyright © 2020-2023  润新知