zoukankan      html  css  js  c++  java
  • HDU 1573 X问题(中国剩余定理标准解法)

    X问题

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 8354    Accepted Submission(s): 3031

     

    Problem Description

    求在小于等于N的正整数中有多少个X满足:X mod a[0] = b[0], X mod a[1] = b[1], X mod a[2] = b[2], …, X mod a[i] = b[i], … (0 < a[i] <= 10)。

    Input

    输入数据的第一行为一个正整数T,表示有T组测试数据。每组测试数据的第一行为两个正整数N,M (0 < N <= 1000,000,000 , 0 < M <= 10),表示X小于等于N,数组a和b中各有M个元素。接下来两行,每行各有M个正整数,分别为a和b中的元素。

    Output

    对应每一组输入,在独立一行中输出一个正整数,表示满足条件的X的个数。

    Sample Input

    3 10 3 1 2 3 0 1 2 100 7 3 4 5 6 7 8 9 1 2 3 4 5 6 7 10000 10 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9

    Sample Output

    1 0 3

    linle   |   We have carefully selected several similar problems for you:  1788 1695 1452 1060 1299 

    中国剩余定理(a[i]不一定互质的情况):
    	ans%a1=r1,ans%a2=r2,求最小的ans;
    	解方程a1*x1+r1=a2*x2+r2;
    	则a1*x1-a2*y1=r2-r1;
    	利用拓展欧几里得解a1*x2-a2*y2=d;
    	得出d=gcd(a1,a2);
    	只有(r2-r1)%d=0时方程有解
    	从而得出x1=x2*(r2-r1)/d,y1=y2*(r2-r1)/d;
    	p=a2/d;
    	a1*x1+a2*y1=r2-r1;
    	a1*(x1+a2/d)-a2*(y1-a1/d)=r2-r1;
    	x1=(x1*(r2-r1)%p+p)%p;//使x为最小的正整数解
    	最终ans=a1*x1+r1;
    #include<iostream>
    #define ll long long
    using namespace std;
    ll a[13],b[13];
    void exgcd(ll m,ll n,ll &gcd,ll &x,ll &y){
            if(!n){
                    gcd=m;//printf("gcd=%lld
    ",gcd);
                    x=1,y=0;
            }else{
                    exgcd(n,m%n,gcd,x,y);
                    ll tmp=x;
                    x=y;
                    y=tmp-(m/n)*y;
            }
    }
    int main()
    {
            int T;
            scanf("%d",&T);
            while(T--){
                    ll maxn,n;
                    scanf("%lld%lld",&maxn,&n);
                    for(int i=0;i<n;i++)
                            scanf("%lld",&a[i]);
                    for(int i=0;i<n;i++)
                            scanf("%lld",&b[i]);
                    bool flag=0;
                    ll a1=a[0],b1=b[0];
                    for(int i=1;i<n;i++)
                    {
                            ll x,y,gcd,a2=a[i],b2=b[i];
                            exgcd(a1,a2,gcd,x,y);
                            if((b2-b1)%gcd){
                                    flag=1;break;
                            }
                            ll k=(b2-b1)/gcd,p=a2/gcd;
                            x=(x*k%p+p)%p;//使x为最小的正整数解
                            b1=a1*x+b1;
                            a1=a1/gcd*a2;
                    }
                    if(flag||b1>maxn){
                            printf("0
    ");
                    }else{
                            int ans=b1?1:0;//b1=0时b1不能作为解
                            while(b1+a1<=maxn)
                                    b1+=a1,ans++;
                            printf("%d
    ",ans);
                    }
            }
            return 0;
    }
    
  • 相关阅读:
    Python Django 编写一个简易的后台管理工具2-创建项目
    leetcode-解题记录 771. 宝石与石头
    leetcode-解题记录 1108. IP 地址无效化
    Python Django 编写一个简易的后台管理工具1-安装环境
    备忘录
    Pollard_rho 因数分解
    ProgrammingContestChallengeBook
    HDU ACM-Steps
    ARCH-LINUX 折(安)腾(装)记
    各种Python小玩意收集
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/10182218.html
Copyright © 2011-2022 走看看