• HDU 1573 X问题


    http://acm.hdu.edu.cn/showproblem.php?pid=1573

    解出最小解rr后,特判下其是否为0,为0的话,就直接n / lcm

    否则 + 1

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    
    const int maxn = 500 + 20;
    LL mod[maxn];
    LL r[maxn];
    LL gcd(LL n, LL m) {
        if (n % m == 0) return m;
        else return gcd(m, n % m);
    }
    LL lcm(LL n, LL m) {
        return n / gcd(n, m) * m;
    }
    LL exgcd (LL a,LL mod,LL &x,LL &y) {
        //求解a关于mod的逆元     ★:当且仅当a和mod互质才有用
        if (mod==0) {
            x=1;
            y=0;
            return a;//保留基本功能,返回最大公约数
        }
        LL g=exgcd(mod,a%mod,x,y);
        LL t=x;    //这里根据mod==0  return回来后,
        x=y;    //x,y是最新的值x2,y2,改变一下,这样赋值就是为了x1=y2
        y=t-(a/mod)*y;    // y1=x2(变成了t)-[a/mod]y2;
        return g;            //保留基本功能,返回最大公约数
    }
    bool get_min_number (LL a,LL b,LL c,LL &x,LL &y) {  //得到a*x+b*y=c的最小整数解
        LL abGCD = gcd(a,b);
        if (c % abGCD != 0) return false;//不能整除GCD的话,此方程无解
        a /= abGCD;
        b /= abGCD;
        c /= abGCD;
        LL tx,ty;
        exgcd(a,b,tx,ty); //先得到a*x+b*y=1的解,注意这个时候gcd(a,b)=1
        x = tx * c;
        y = ty * c; //同时乘上c,c是约简了的。得到了一组a*x + b*y = c的解。
        LL haveSignB = b;
        if (b < 0) b = -b;   //避免mod负数啊,模负数没问题,模了负数后+负数就GG
        x = (x % b + b) % b; //最小解
    //    if (x == 0) x = b; //避免x = 0不是"正"整数  不要用这个,溢出
        y = (c - a * x) / haveSignB;
        return true;//true代表可以
    }
    
    void work () {
        LL n, m;
        cin >> n >> m;
        for (int i = 1; i <= m; ++i) {
            cin >> mod[i];
        }
        for (int i = 1; i <= m; ++i) {
            cin >> r[i];
        }
        LL mm = mod[1];
        LL ansx = 0;
        LL rr = r[1];
        for (int i = 2; i <= m; ++i) {
            LL x, y;
            bool ret = get_min_number(mm, -mod[i], r[i] - rr, x, y);
            if (ret == false) {
                printf("0
    ");
                return;
            }
            ansx = mm * x + rr;
            mm = lcm(mm, mod[i]);
            rr = ansx % mm;
        }
        int add = rr != 0;
        if (rr > n) {
            printf("0
    ");
            return ;
        }
        cout << (n - rr) / mm + add << endl;
        return ;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        int t;
        cin >> t;
        while (t--) work();
        return 0;
    }
    View Code
  • 相关阅读:
    洛谷P3224 [HNOI2012]永无乡 线段树合并
    洛谷P3605 [USACO17JAN]Promotion Counting——线段树合并
    python之三元表达式、列表推导、生成器表达式、递归、匿名函数、内置函数
    python之迭代器、生成器与面向过程编程
    Python之函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器
    Python之函数基础
    Python之字符编码与文件操作
    Python基本数据类型
    python介绍
    编程基础
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/5926439.html
Copyright © 2020-2023  润新知