zoukankan      html  css  js  c++  java
  • 51nod 1352 扩展欧几里德

    给出N个固定集合{1,N},{2,N-1},{3,N-2},...,{N-1,2},{N,1}.求出有多少个集合满足:第一个元素是A的倍数且第二个元素是B的倍数。

    提示:

    对于第二组测试数据,集合分别是:{1,10},{2,9},{3,8},{4,7},{5,6},{6,5},{7,4},{8,3},{9,2},{10,1}.满足条件的是第2个和第8个。

    Input
    第1行:1个整数T(1<=T<=50000),表示有多少组测试数据。
    第2 - T+1行:每行三个整数N,A,B(1<=N,A,B<=2147483647)
    Output
    对于每组测试数据输出一个数表示满足条件的集合的数量,占一行。
    Input示例
    2
    5 2 4
    10 2 3
    Output示例
    1
    2

      根据题意,设每一组为(x,y),并且 x = k1 * A , y = k2 * B;(k1,k2为正整数) ,并且x + y = n + 1;
    得到不定方程k1*A + k2*B = n+1。 根据扩展欧几里德算法得到一组解,计算满足条件的有多少组即可。
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 1000000001
    #define ll __int64
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int MAXN = 50010;
    ll A,B,n;
    int gcd(int a,int b)
    {
        return b > 0 ? gcd(b,a%b):a;
    }
    ll exgcd(ll a,ll b,ll &x,ll &y)
    {
        if(b == 0){
            x = 1;
            y = 0;
            return a;
        }
        ll r = exgcd(b,a%b,x,y);
        ll t = x;
        x = y;
        y = t - (a/b) * y;
        return r;
    }
    ll getnum(ll x,ll k)
    {
        double l = -(x * 1.0)/k;
        if(l <= 0){
            return (ll)l;
        }
        if(x % k){
            return -x/k + 1;
        }
        return x/k;
    }
    ll getnum1(ll n,ll B,ll y,ll k)
    {
        ll t = (y - n / B) / k;
        if(B*(y - k * t) > n){
            t ++;
        }
        return t;
    }
    int main()
    {
        int t;
        ll ans, x, y;
        cin >>t;
        while(t--){
    
            cin >>n >>A >>B;
            ans = 0;
            int ret = exgcd(A,B,x,y);
            if((n+1) % ret != 0){
                ans = 0;
            }
            else {
                ll rt = (n+1) / ret;
                x *= rt;
                y *= rt;
                ll k1 = B / ret;
                ll k2 = A / ret;
    
                //cout<<x<<' '<<y<<endl;
                 ll f,b;
                 ll c_x = getnum(x,k1);
                 ll c_y = getnum1(n,B,y,k2);
                 f = max(c_x,c_y);
                 ll fp1 = (n / A - x)/k1;
                 if(A*(x+k1*fp1) > n) fp1 --;
                 ll fp2 = y / k2;
                 b = min(fp2,fp1);
                 ans = (b - f + 1);
            }
            cout<<(ans > 0 ? ans : 0)<<endl;
        }
    }
    
    
    





  • 相关阅读:
    Swift语法基础: 20
    Swift语法基础:19
    Swift语法基础:18
    Swift语法基础:17
    Swift语法基础:16
    Swift语法基础:15
    Swift语法基础:14
    Swift语法基础:13
    Swift语法基础:12
    Swift语法基础:11
  • 原文地址:https://www.cnblogs.com/sweat123/p/5315907.html
Copyright © 2011-2022 走看看