SGU 106 The equation

我的思路就是首先把一个基本解求出来,然后看在x1、x2的范围内x的范围是多少,然后找到对应的y的范围,再看y的范围有多少个解是在y1、y2范围之内的,这个就是最后的答案。

当然,对于含有a=0或b=0的情况要特判一下。

#include <iostream>
using namespace std;
typedef long long LL;
LL a,b,c,x1,x2,y1,y2,x,y,tmp,ans=0;
LL mini = -361168601842738790LL;
LL maxi = 322337203685477580LL;
int extendedGcd(int a,int b){
    if (b==0){
    x=1;y=0;
    return a;
    }
    else{
    int tmp = extendedGcd(b,a%b);
    int t = x;
    x=y;
    y=t-a/b*y;
    return tmp;
    }
}
LL extendedGcd(LL a,LL b){
    if (b == 0){
    x=1;y=0;
    return a;
    }
    else{
    LL TEMP = extendedGcd(b,a%b);
    LL tt=x;
    x=y;
    y=tt-a/b*y;
    return TEMP;
    }
}
LL upper(LL a,LL b){
    if (a<=0)
    return a/b;
    return (a-1)/b + 1;
}
LL lower(LL a,LL b){
    if (a>=0)
    return a/b;
    return (a+1)/b - 1;
}
void update(LL L,LL R,LL wa){
    if (wa<0){
    L=-L;R=-R;wa=-wa;
    swap(L,R);
    }
    mini=max(mini,upper(L,wa));
    maxi=min(maxi,lower(R,wa));
}
int main(){
    cin >> a >> b >> c >> x1 >> x2 >> y1 >> y2;c=-c;
    if (a==0 && b==0){
    if (c==0) ans = (x2-x1+1) * (y2-y1+1);
    }
    else if (a==0 && b!=0){
    if (c % b==0) {
        tmp = c/b;
        if (tmp>=y1 && tmp<=y2) ans = 1;
    }
    }
    else if (a!=0 && b==0){
    if (c % a==0){
        tmp = c/a;
        if (tmp>=x1 && tmp<=x2) ans = 1;
    }
    }
    else{
    LL d = extendedGcd(a,b);
    if (c%d == 0){
        LL p = c/d;
        update(x1-p*x,x2-p*x,b/d);
        update(y1-p*y,y2-p*y,-a/d);
        ans = maxi-mini+1;
        if (ans<0) ans=0;
    }
    }
    cout << ans << endl;
}
时间: 2024-12-20 16:58:50

SGU 106 The equation的相关文章

数论 + 扩展欧几里得 - SGU 106. The equation

The equation Problem's Link Mean: 给你7个数,a,b,c,x1,x2,y1,y2.求满足a*x+b*y=-c的解x满足x1<=x<=x2,y满足y1<=y<=y2.求满足条件的解的个数. analyse: 做法是扩展欧几里德. 1.首先是欧几里德算法,欧几里德算法是用于求任意两个数的最大公约数(gcd(a,b)), 这个方法基于一个定理,gcd(a,b)=gcd(b,a % b)(a>b),%表示取模. 我们来证明上述定理,因为a>b,

SGU 106. The equation 扩展欧几里德

求解的个数 对应ax+by=c 根据裴蜀定理c%gcd(a, b) == 0有解 假设d = gcd(a, b) 用扩展欧几里德求出方程aax+bb*y=cc 的解x0 y0 那么原方程的一个解就是x0*c/d和y0*c/d 通解为 x = x0+i*b/d y = y0+i*a/d 分别讲x1 x2 带入得到i 满足最小的左区间 y1 y2一样 #include <cstdio> #include <cstring> #include <algorithm> usin

The equation - SGU 106(扩展欧几里得)

题目大意:有一个二元一次方程,给出系数值和x与y的取值范围,求出来总共有多少对整数解. 分析:有以下几点情况. 1,系数a=0, b=0, 当c != 0的时候结果很明显是无解,当c=0的时候x,y可以为任意值,答案就是(x2-x1+1)*(y2-y1+1) 2,系数a=0, b!=0, 先判断y的唯一解是否是整数,并且在[y1,y2]范围内,如果在,答案就是x的个数,x2-x1+1,否则为0 3,系数b=0,  a!=0, 先判断x的唯一解是否是整数,并且在[x1,x2]范围内,如果在,答案就

kuangbin 带你飞 数学基础

模版整理: 晒素数 void init() { cas = 0; for (int i = 0 ; i < MAXD ; i++) is_prime[i] = true; is_prime[0] = is_prime[1] = false; for (int i = 2 ; i < MAXD ; i++) { if (is_prime[i]) { prime[cas++] = i; for (int j = i + i ; j < MAXD ; j += i) is_prime[j] =

好题、趣题、麻烦题

sgu 106: 这道题首先让我们解一个线性方程式ax+by=-c,用拓展欧几里得就可以搞定.但是它要求我们需要输出满足x1<=x<=x2,y1<=y<=y2的解的个数,这可就没那么简单了... 我一开始想记录x和y的边界值,但想了好久,分了n多种情况...因为太繁琐,最后索性放弃分情况,交了一发WA了. 看了某人的解题报告后,发现原来可以求满足x1<=x0+k*r1<=x2,y1<=y0-k*r2<=y2的k的个数.r1=lcm/a,r2=lcm/b,lc

SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)

题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operations with int64 type, all Delphi solutions for the problem 455 (Sequence analysis) run much slower than the same code written in C++ or Java. We do not gua

SGU 438 The Glorious Karlutka River =) 拆点+动态流+最大流

The Glorious Karlutka River =) Time Limit:500MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice SGU 438 Appoint description: Description A group of Mtourists are walking along the Karlutka river. They want to cross

SGU - 107 - 987654321 problem (简单数学!)

SGU - 107 987654321 problem Time Limit: 250MS   Memory Limit: 4096KB   64bit IO Format: %I64d & %I64u Submit Status Description For given number N you must output amount of N-digit numbers, such, that last digits of their square is equal to 987654321

sgu Kalevich Strikes Back

这道题就是求一个大矩形被n个矩形划分成n+1个部分的面积,这些矩形之间不会相交,可能包含.. 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 #define maxn 120100 6 using namespace std; 7 8 long long s[maxn]; 9 vector<int>g[maxn]; 10 i