裴蜀定理

在数论中,裴蜀等式或裴蜀定理是一个关于最大公约数(或最大公约式)的定理。裴蜀定理得名于法国数学家艾蒂安·裴蜀,说明了对任何整数a、b和它们的最大公约数d,关于未知数x和y的线性丢番图方程(称为裴蜀等式):

ax+by=m
有整数解时当且仅当m是d的倍数。裴蜀等式有解时必然有无穷多个整数解,每组解x、y都称为裴蜀数,可用扩展欧几里得算法求得。
例如,12和42的最大公约数是6,则方程12x+42y=6有解。事实上有(-3)×12 + 1×42 = 6及4×12 + (-1)×42 = 6。特别来说,方程 ax+by=1 有整数解当且仅当整数a和b互素。

Bzoj【2257】: [Jsoi2009]——瓶子和燃料

Time Limit: 10 Sec Memory Limit: 128 MB

Description

jyy就一直想着尽快回地球,可惜他飞船的燃料不够了。有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子来换。jyy的飞船上共有 N个瓶子(1<=N<=1000) ,经过协商,火星人只要其中的K 个 。 jyy将 K个瓶子交给火星人之后,火星人用它们装一些燃料给 jyy。所有的瓶子都没有刻度,只在瓶口标注了容量,第i个瓶子的容量为Vi(Vi 为整数,并且满足1<=Vi<=1000000000 ) 。火星人比较吝啬,他们并不会把所有的瓶子都装满燃料。他们拿到瓶子后,会跑到燃料库里鼓捣一通,弄出一小点燃料来交差。jyy当然知道他们会来这一手,于是事先了解了火星人鼓捣的具体内容。火星人在燃料库里只会做如下的3种操作:
1、将某个瓶子装满燃料;
2、将某个瓶子中的燃料全部倒回燃料库;
3、将燃料从瓶子a倒向瓶子b,直到瓶子b满或者瓶子a空。燃料倾倒过程中的损耗可以忽略。火星人拿出的燃料,当然是这些操作能得到的最小正体积。
jyy知道,对于不同的瓶子组合,火星人可能会被迫给出不同体积的燃料。jyy希望找到最优的瓶子组合,使得火星人给出尽量多的燃料。

Input

第1行:2个整数N,K,
第2..N 行:每行1个整数,第i+1 行的整数为Vi

Output

仅1行,一个整数,表示火星人给出燃料的最大值。

Sample Input

3 2

3

4

4

Sample Output

4

HINT

选择第2 个瓶子和第 个瓶子,火星人被迫会给出4 体积的容量。

裴蜀定理的应用,将每个数的因子进行排序,选出最大的因子,并且个数大于等于k就是答案

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int Max  = 1e6+100;
int a[Max];
void Get(int x){
    for(int i = 1;i*i<=x;i++){
        if(x%i == 0) a[++a[0]] = i;
        if(x%i == 0 && x/i!=i) a[++a[0]] = x/i;
    }
}

int main(){
    int n,x,k;
    scanf("%d %d",&n,&k);
    a[0] = 0;
    for(int i = 0;i<n;i++){
        scanf("%d",&x);
        Get(x);
    }
    sort(a+1,a+a[0]+1);
    int ans  = 0;
    int num = 1;
    for(int i = a[0]-1;i>=1;i--){
        if(a[i]==a[i+1]) num++;
        else {
            if(num>=k) {ans = a[i+1];break;}
            num =1;
        }
    }
    printf("%d\n",ans);
    return 0;
}

【Bzoj】2299: [HAOI2011]——向量

Time Limit: 10 Sec Memory Limit: 256 MB

Description

给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y)。

说明:这里的拼就是使得你选出的向量之和为(x,y)

Input

第一行数组组数t,(t<=50000)

接下来t行每行四个整数a,b,x,y (2×109<=a,b,x,y<=2×109)

Output

t行每行为Y或者为N,分别表示可以拼出来,不能拼出来

Sample Input

3
2 1 3 3
1 1 0 1
1 0 -2 3

Sample Output

Y
N
Y
HINT
样例解释:
第一组:(2,1)+(1,2)=(3,3)
第三组:(-1,0)+(-1,0)+(0,1)+(0,1)+(0,1)=(-2,3)

通过观察可以发现,总共就四种操作 x±2a,y±2b,x+a,y+b,x+b,y+a ,也可以确定三四操作只会出现一次,那么我们枚举三四操作,根据裴蜀定理判断是否符合条件。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <algorithm>

using namespace std;

typedef long long LL;

LL gcd(LL a,LL b) {
    return b ==0?a:gcd(b,a%b);
}
LL ok(LL x,LL y,LL g) {
    return (x%g ==0 && y%g ==0);
}
int main() {
    LL a,b,x,y;
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%lld %lld %lld %lld",&a,&b,&x,&y);
        LL g = gcd(2*a,2*b);
        if(ok(x,y,g)||ok(x+a,y+b,g)||ok(x+b,y+a,g)||ok(x+a+b,y+a+b,g)) printf("Y\n");
        else printf("N\n");
    }
    return 0;
}

你可能感兴趣的:(裴蜀定理)