扩展欧几里德--解的个数

解的个数

已知整数x,y满足如下面的条件:

  ax+by+c = 0

  p<=x<=q

  r<=y<=s

求满足这些条件的x,y的个数。

输入描述 Input Description

第一行有一个整数nn<=10),表示有n个任务。n<=10

以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s。均不超过108

输出描述

n行,第i行是第i个任务的解的个数。

样例输入

2

2 3 -7 0 10 0 10

1 1 1 -10 10 -9 9

样例输出

1

19

#include<cstdio>
#include<cmath>
int x,y,a,b,c,n,g;
long long ans,p,q,r,s;
int exgcd(int a,int b,int *x,int *y)//拓展欧几里德;
{
 if(b==0){*x=1;*y=0;return a;}
 int d=exgcd(b,a%b,x,y);
 int z=*x;*x=*y;*y=z-*y*(a/b);
 return d;
}
void zhao1(int x,int y)
{
 if((x<=q)&&(x>=p)&&(y>=r)&&(y<=s))ans++;
 if(x<=q){
  if(b/g>0){x+=b/g;y-=a/g;zhao1(x,y);}//别把zhao1 放外面,b/g=0时会被卡挂了;
  else if(b/g<0){x-=b/g;y+=a/g;zhao1(x,y);}  
 }
}
void zhao2(int x,int y)
{
 if((x<=q)&&(x>=p)&&(y>=r)&&(y<=s))ans++;
 if (x>=p){
  if(b/g>0){x-=b/g;y+=a/g;zhao2(x,y);}
  else if(b/g<0){x+=b/g;y-=a/g;zhao2(x,y);}  
 }
}
int main()
{
 scanf("%d",&n);
 for(int i=1;i<=n;i++)
 {
  ans=0;
  scanf("%d%d%d%I64d%I64d%I64d%I64d",&a,&b,&c,&p,&q,&r,&s);
  if(s<r||q<p){printf("%I64d\n",ans);continue;}//x或y的可行域不存在时,结果为0;
  if(a==0&&b==0&&c==0) //a,b,c均为0时 ,x,y可以是任意值;
   {s=s-r+1;q=q-p+1;ans=q*s;printf("%I64d\n",ans);continue;}
  if(a==0&&b==0&&c!=0) //a=b=0,c!=0时 ,无解;
   {printf("%I64d\n",ans);continue;}
  c=-c;                //将c调到等号右边;
  g=exgcd(a,b,&x,&y);  //找到a,b的最大公因数;并且找到一组ax+by=1的一组解;
  x*=c/g;y*=c/g;       //得到ax+by=c时 的一组解;
  if(a*x+b*y!=c)       //等号可能不成立,例2 0 1 ;
       {ans=0;printf("%ld\n",ans);continue;}
  zhao1(x,y);          //分别向x变大和变小的方向找在[p,q] 之间的解;
  zhao2(x,y);
  if((x<=q)&&(x>=p)&&(y>=r)&&(y<=s)) ans-=1;//x,y符合要求时,两次递归多加了一次;
  printf("%I64d\n",ans);
 }
 return 0;
}

//自认为要懂扩展欧几里德有点难,偷个懒,背个代码。。。。

时间: 2024-10-12 21:49:41

扩展欧几里德--解的个数的相关文章

扩展欧几里德解的数量(51nod 1352)

题意:给出N,A,B:求A*x+ B*y = N+1   的大于0 的解的数量: 思路:先用exgcd求出大于0的初始解x,rest = N - x*A; sum = rest/LCM(A, B); #include <iostream> #include <algorithm> #include <stdlib.h> #include <time.h> #include <cmath> #include <cstdio> #incl

URAL 1204. Idempotents 扩展欧几里德

题目来源:URAL 1204. Idempotents 题意:输入n(n = p*q p,q是质数) 并且x*x=x(mod n) 求x 思路: x*x=x(mod n)  -> x*x+k*n=x -> x*(x-1)/n = k 所以 0 和 1 是一组解 因为n = p*q 且x*(x-1)%(p*q)== 0 x < n 因为x*x%n == x 模n之后才是x 1.x有p因子x-1有q因子 x%p == 0且(x-1)%q == 0 a*p == x且b*q == x-1 得到

扩展欧几里德算法详解

扩展欧几里德算法 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了,这就是欧几里德算法,用 C++ 语言描述如下: 由于是用递归写的,所以看起来很简洁,也很好记忆.那么什么是扩

扩展gcd codevs 1213 解的个数

codevs 1213 解的个数 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 已知整数x,y满足如下面的条件: ax+by+c = 0 p<=x<=q r<=y<=s 求满足这些条件的x,y的个数. 输入描述 Input Description 第一行有一个整数n(n<=10),表示有n个任务.n<=10 以下有n行,每行有7个整数,分别为:a,b,c,p,q,r,s.均不超过108. 输出描述 O

欧几里德和扩展欧几里德详解 以及例题CodeForces 7C

欧几里德定理: 对于整数a,b来说,gcd(a, b)==gcd(b, a%b)==d(a与b的最大公约数),又称为辗转相除法 证明: 因为a是d的倍数,b是d的倍数:所以a%d==0:b%d==0: 设k=a/b:r=a%b:则 a=k*b+r: 由上得出:r=a-k*b: 因为a和b都是d的倍数,所以(a-k*b)也是d的倍数,所以r也是d的倍数: 所以gcd(a, b)==gcd(b, a%b)==d 而为什么要证明gcd(a, b)==gcd(b, a%b)==d这个式子成立呢? 其实证

欧几里德及扩展欧几里德——详解

欧几里德定理: 对于整数a, b来说有,gcd (a, b) == gcd (b, a%b) == d,又称为辗转相除法. 欧几里德证明: 先进行设定:x, y, t, k 为整数,并且有d*x == a, d*y == b. t = a - b. k = a / b. 那么t = d*x - d*k*y; t = d * (x - k * y); 故 t % d == 0; 所以gcd (b, t) == d == gcd (b, a%b) == gcd (a, b); 证毕. 欧几里德应用:

扩展欧几里德算法

文章来源:http://blog.csdn.net/zhjchengfeng5/article/details/7786595 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了

POJ2142 The Balance (扩展欧几里德)

本文为博主原创文章,欢迎转载,请注明出处 www.cnblogs.com/yangyaojia The Balance 题目大意  你有一个天平(天平左右两边都可以放砝码)与重量为a,b(1<=a,b<=10000)的两种砝码.让你求出一种方案称出重为c(1<=c<=50000)的物品,如有多种方案,请输出两种砝码需要数量的总和最小的方案. 输入 有若干行,每行三个数,a,b,c. 结束时用0 0 0表示. 输出 若干行,每行两个数,表示每个询问中a的数量与b的数量 如果无解输出 

【转】扩展欧几里德

http://blog.csdn.net/zhjchengfeng5/article/details/7786595 扩展欧几里德算法 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大