zoukankan      html  css  js  c++  java
  • cqyz oj | 解的个数 | Exgcd

    Description

      已知x,y满足如下条件:
      ax+by+c=0 ; x1 <= x <= x2 ; y1 <= y <= y2 ; x,y均为整数。
      其中:a,b,c,x1,x2,y1,y2 都是绝对值不超过 10^8 的整数。
      求(x,y)的解的个数。

    Input

      第一行:n  说明:有 n 个任务。n<=10。之后有 n 行,每行为:a,b,c,x1,x2,y1,y2

    Output

      有n行,第i行是第i个任务的结果。

    Sample Input 1 

    2
    2 3 -7 0 10 0 10
    1 1 1 -10 10 -9 9

    Sample Output 1

    1
    19
    

    Hint

    -100000000 <= a,b,c,x1,x2,y1,y2 <= 100000000

    扩欧例题。
    求范围中解的个数时用通解 列不等式:
    x1 <= x0+k*b/gcd <= x2
    y1 <= x0-k*a/gcd <= y2
    变形可得到两个关于k的区间,求交集包含的整点个数即可
    #include<bits/stdc++.h>
    #define lowbit(x) (x&(-x))
    #define mst(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    LL read() {
        LL o=0, f=1;
        char ch;
        while(!isdigit(ch=getchar())) if(ch == '-') f=-1;
        while(isdigit(ch)) o=o*10+ch-'0', ch = getchar();
        return o*f;
    }
    
    const int maxn = 100005, maxm = 500005;
    
    LL Exgcd(LL a, LL b, LL &x, LL &y) {
        if(b == 0) { x=1, y=0; return a; }
        LL gcd = Exgcd(b, a%b, y, x);
        y = y-a/b*x;
        return gcd;
    }
    
    int len(double a, double b, double c, double d) { // 求[a,b],[c,d]交集含整点个数 
        a = ceil(a), c = ceil(c), b = floor(b), d = floor(d);
        return max((int)((min(b, d)-max(a, c)))+1, 0);
    }
    
    LL a, b, c, d, x, y, X, Y;
    inline bool inRangex(LL n) { return x<=n && n<=X; }
    inline bool inRangey(LL n) { return y<=n && n<=Y; }
    
    int main() {
        LL n = read();
        while(n--) {
            a=read(), b=read(), c=read(), x=read(), X=read(), y=read(), Y=read();
            if(x>X || y>Y) { puts("0"); continue; }
            c = -c; // ax+by=c
            //a, b, c都要进行非负处理orz
            if(c<0) c=-c, a=-a, b=-b;
            if(a<0) a=-a, swap(x=-x, X=-X);
            if(b<0) b=-b, swap(y=-y, Y=-Y);
            if(!a && !b) {
                printf("%lld
    ", c ? 0 : (LL)(X-x+1)*(Y-y+1));
            }
            else if(!a) {
                if(c%b != 0 || !inRangey(c/b)) puts("0");
                else printf("%d
    ", X-x+1);
            }
            else if(!b) {
                if(c%a != 0 || !inRangex(c/a)) puts("0");
                else printf("%d
    ", Y-y+1);
            }
            else {
                LL x0, y0;
                LL gcd = Exgcd(a, b, x0, y0);
                if(c%gcd != 0) { puts("0"); continue; }
                a/=gcd, b/=gcd, c/=gcd;
                x0 *= c, y0 *= c;
                printf("%d
    ", len(1.0*(x-x0)/b, 1.0*(X-x0)/b, 1.0*(y0-Y)/a, 1.0*(y0-y)/a));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    CentOS 安装 Xamarin官方Mono
    mongo命令行下去除重复的数据
    通过前端js将页面表格导出为PDF(二)
    通过前端js将页面表格导出为PDF(一)
    ubuntu下手动安装MongoDB
    在django项目下执行定时任务
    django+uwsgi+nginx部署在ubuntu系统上
    Nginx(三)
    Nginx(二)
    Nginx(一)
  • 原文地址:https://www.cnblogs.com/de-compass/p/12209276.html
Copyright © 2011-2022 走看看