扩展欧几里得求两多项式最大公因式

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>

using namespace std;
typedef long long LL;
const double eps = 1e-8;
const int MOD = 999983;
const int N = 55;

struct Poly
{
    int n;
    LL a[N];
};

Poly p[25];

LL gcd(LL a,LL b)
{
    return b? gcd(b,a%b):a;
}

Poly delete_zero(Poly x)
{
    int i,j;
    Poly tmp;
    for(i=0;i<x.n && x.a[i] == 0;i++);
    for(j=0;i<x.n;i++,j++) tmp.a[j] = x.a[i];
    tmp.n = j;
    return tmp;
}

Poly poly_gcd(Poly x,Poly y)
{
    x = delete_zero(x);
    y = delete_zero(y);
    Poly yy = y,tmp;
    tmp.n = 0;
    int i=0;
    if(x.n == y.n)
    {
        double k = x.a[0] / y.a[0];
        for(i=1;i<x.n;i++)
            if(fabs(x.a[i]*1.0 - k*y.a[i]) > eps) break;
        if(i == x.n) return y;
    }
    LL g = gcd(x.a[0],y.a[0]);
    LL tx = y.a[0] / g;
    LL ty = x.a[0] / g;
    for(i=0;i<x.n;i++)
    {
        x.a[i] *= tx;
        x.a[i] %= MOD;
    }
    for(i=0;i<y.n;i++)
    {
        y.a[i] *= ty;
        y.a[i] %= MOD;
    }
    if(x.n < y.n) swap(x,y);
    for(i=1;i<y.n;i++)
        tmp.a[i-1] = ((x.a[i] - y.a[i])%MOD + MOD)%MOD;
    for(;i<x.n;i++)
        tmp.a[i-1] = x.a[i];
    tmp.n = x.n - 1;
    tmp = delete_zero(tmp);
    if(tmp.n == 0) return yy;
    return poly_gcd(y,tmp);
}
时间: 2024-08-01 21:04:12

扩展欧几里得求两多项式最大公因式的相关文章

POJ2447 分解因数+扩展欧几里得+高次幂取模

昨天一天弄明白的pollard-rho启发式因数分解没想到今天就用上了 而且是一次过 感觉好有成就感  题目大意 给你N=P*Q 先把p q从N因数分解出来 得到具体的值 然后(p-1)*(q-1)=t 从而求出t的值 有了t的值 根据e*d(mod t)=1 求出e模t的逆元d 注意求出的逆元可能为负 然后求c^d%n 为m 就是 题目要求的值 这题的解题步骤如下 1根据pollard-rho启发式因数分解 把n分解成两个素数p q; 2(p-1)*(q-1)求出t的值 3通过扩展欧几里得 求

POJ1061 扩展欧几里得

根据题意得出的方程 (m-n)t+Lk=y-x t为步数 k为圈数 然后根据扩展欧几里得就能得出解 然后处理一下就可以了 对L取余要防止负数情况 #include <iostream> #include<cstdio> using namespace std; void exgcd(long long a,long long b,long long &d,long long &x,long long &y) { if(b==0) { x=1;y=0;d=a;

POJ2115 扩展欧几里得

扩展欧几里得模板题 根据题意理出二元一次方程 A+X*C-B=Y*2^k 移项可得X*C+Y*2^k=B-A  然后扩展欧几里得 就得出答案了 #include <iostream> #include<cstdio> #include<cstring> using namespace std; void exgcd(long long a,long long b,long long &d,long long &x,long long &y) {

POJ 2142 扩展欧几里得

这题问的是|x|+|y|最小的时候 讨论一下当取x最小正整数解的时候 通过x求出y 当y取最小正整数解的时候通过y求出x  只有这两种情况因为情况的x和y都比这两种情况的大  所以只需要比较这两种情况的特解就可以得出答案 #include <iostream> #include<cstdio> #include<cstring> using namespace std; void exgcd(long long a,long long b,long long &

最古老的算法:辗转相除法(求两个自然数最大公约数)

在数学界,辗转相除法,又称欧几里得算法,被认为是世界上最早的算法(公元前300年),该算法用于求两个最大公约数的算法.辗转相除法首次出现于欧几里得的<几何原本>(第VII卷,命题yⅠ和Ⅱ)中,而在中国则可以追溯至东汉出现的<九章算术>. 两个自然数的最大公约数是能够同时整除它们的最大的正整数.辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的相除余数的最大公约 数.例如,1254和390的最大公约数是6(1254 = 6 × 209:390 = 6 × 65):用

世界上最早的算法:辗转相除法(求两个自然数最大公约数)

      在数学界,辗转相除法,又称欧几里得算法,被认为是世界上最早的算法(公元前300年),该算法用于求两个最大公约数的算法.辗转相除法首次出现于欧几里得的<几何原本>(第VII卷,命题yⅠ和Ⅱ)中,而在中国则可以追溯至东汉出现的<九章算术>.     两个自然数的最大公约数是能够同时整除它们的最大的正整数.辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的相除余数的最大公约数.例如,1254和390的最大公约数是6(1254 = 6 × 209:390 =

php的类里可以有两个构造函数?

问题描述 php的类里可以有两个构造函数? class ecs_error { var $_message = array(); var $_template = ''; var $error_no = 0; /** * 构造函数 * * @access public * @param string $tpl * @return void */ function __construct($tpl) { $this->ecs_error($tpl); } /** * 构造函数 * * @acces

如何求两个数组的交集

题目意思大概是这样的:给定两个大数组(1w以上1亿以下),用最有效的方法找出来两个数组的交集. 对于这道题,我有一个思路就是,先对数组进行排序,然后用两个指针在已排序的数组上轮流指向头结点,进行比较. 比较亮的地方,就是在于这个比较的方式了. 首先,比较的时候,要先确定两个指针指向的内用是否一致.如果一致,那么这个点,就是交集的一个元素,没问题吧? 这里有一个问题就是,接下来如何比较? 步骤是这样的:先比较两个指针指向内容的大小,指向结果小的指针,开始递增,直到较小的指针指向的值大于或等于另一个

分析MS SQL Server里函数的两种用法

server|函数 SQL Server里函数的两种用法(可以代替游标) 1. 因为update里不能用存储过程,然而要根据更新表的某些字段还要进行计算.我们常常采用游标的方法,这里用函数的方法实现. 函数部分: 以下是引用片段: CREATE FUNCTION [DBO].[FUN_GETTIME] (@TASKPHASEID INT) RETURNS FLOAT AS BEGIN DECLARE @TASKID INT, @HOUR FLOAT, @PERCENT FLOAT, @RETUR