Codevs1213 解的个数

来源:互联网 发布:程序化交易策略源码 编辑:程序博客网 时间:2024/06/05 02:36

题目描述 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。

输出描述 Output Description
共n行,第i行是第i个任务的解的个数。

样例输入 Sample Input
2
2 3 -7 0 10 0 10
1 1 1 -10 10 -9 9

样例输出 Sample Output
1
19

代码

//By Chorolop#include<cstdio>#include<iostream>using namespace std;void exgcd(long long a,long long b,long long &d,long long &x,long long &y){    if(!b) {x = 1,y = 0,d = a;}    else {exgcd(b,a%b,d,y,x);y -= x*(a/b);}}long long gcd(long long x,long long y){    return (!y)?x:gcd(y,x%y);}int main(){    long long n;    scanf("%lld",&n);    while(n--){        long long a,b,c,p,q,r,s,d,x,y;        scanf("%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&p,&q,&r,&s);        if(q < p || s < r){            printf("0\n");            continue;        }        //SJ 2        if(!a && !b){            if(!c){ printf("%lld\n",(q-p+1)*(s-r+1));            }else{ printf("0\n");}            continue;        }else{            if(!a){                y = -c/b;                if(r <= y && y <= s && -c%b==0) printf("1\n");                else printf("0\n");                continue;            }            if(!b){                x = -c/a;                if(x >= p && x <= q && -c%a==0) printf("1\n");                else printf("0\n");                continue;            }        }        //SJ 3        d = gcd(a,b);        //SJ 1        if(-c%d){            printf("0\n");            continue;        }        a /= d;        b /= d;        c /= d;        exgcd(a,b,d,x,y);        x *= -c,y *= -c;        while(x-b*d >= p) x -= b*d,y += a*d;        int T = 0;        while(x <= q){            if(r <= y && y <= s && x >= p && x <= q)                T++;            x += b*d,y -= a*d;        }        printf("%d\n",T);    }    return 0;}

评价
这道题像数学题一样注重一丝不苟的分类讨论嗯。尤其注意的是几个特殊情况需要特解:
1. a == b == c == 0 或者 a == b == 0 && c != 0
这时候解是无条件的嗯,范围内的每一个整数解都可以
2. a == 0 或者 b == 0
此时显然那个丢番图方程变成了一元一次方程,但是仍然要注意整除性问题——题目说好了x,y都是整数的
3. -c不能被gcd(a,b)整除
显然这个时候无解
4. 输入的解集是个空集
显然这个时候也无解

理论基础
扩展欧几里德 + 不定方程