zoukankan      html  css  js  c++  java
  • 欧拉函数与中国剩余定理

    中国剩余定理(大神博客):https://www.cnblogs.com/MashiroSky/p/5918158.html

    中国剩余定理(大神板子):https://www.cnblogs.com/czsharecode/p/9736807.html

    欧拉函数:欧拉函数是小于x的整数中与x互质的数的个数,一般用φ(x)表示。特殊的,φ(1)=1。

    欧拉函数的公式:φ(x)=x*(1-1/p1)*(1-1/p2).....其实很好理解。在1~x的范围内,去一个数是p1的倍数的概率为1/p1,是p2的倍数的概率是1/p2,不是p1的倍数的概率为1-1/p1,不是p2的倍数的概率为1-1/p2,

    所以不是p1的倍数也不是p2的倍数的概率为(1-1/p1)*(1-1/p2),其余质因子同理。所以φ(x)=x*(1-1/p1)*(1-1/p2).....。

    可以用质因子分解的模板来求欧拉函数:

    void solve(){
        ll m;
        cin>>m;
        ll c=sqrt(m);
        ll ans=m;
        for(ll i=2;i<=c;i++){
            if(m%i==0){
                ans=ans/i*(i-1);
                while(m%i==0){
                    m/=i;
                }
            }
    
        }
        if(m!=1) ans=ans/m*(m-1);
        cout<<ans<<endl;
    }

    欧拉函数例题: X - Same GCDs CodeForces - 1295D 

    题目大意:在区间[0,m-1)内求满足gcd(a,m)=gcd(a+x,m)的个数,根据辗转相除,gcd(a+x,m)=gcd(m,(a+x)%m)=gcd(a,m),令a+x=k,那么gcd(a,m)=gcd(k%m,m)。令i=k%m。那么gcd(a,m)=gcd(i,m)。

    其中0<=i<=m-1。那么就是求gcd(i/q,m/q)=1的个数其中q=gcd(a,m)。也就是求m/q的欧拉函数.

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    void solve()
    {
        ll n,m;
        cin>>n>>m;
        ll c=__gcd(n,m);
        ll a=m/c;
        c=sqrt(a);
        ll ans=a;
        for(ll i=2;i<=c;i++){
            if(a%i==0){
                ans=ans/i*(i-1);
                while(a%i==0){
                    a/=i;
                }
            }
    
        }
        if(a!=1) ans=ans/a*(a-1);
        cout<<ans<<endl;
    }
    int main()
    {
        ll t;
        cin>>t;
        while(t--) solve();
    
    
        return 0;
    }

     中国剩余定理例题:http://poj.org/problem?id=1006  (POJ 1006)

    关于中国剩余定理无非就是求几个方程

    n1=mod1+x1*t1。。。n2=mod2+x2*t2。。。n3=mod3+x3*t3.等等。。。

    n1的求法就是x2与x3的公倍数,然后关于x1求逆元,再乘以mod1,注意这里求逆元时要用exgcd求,不能用ksm,费马小定理要求互质。

    中国剩余定理板子

    void exgcd(ll a,ll b,ll& x,ll& y){
        if(!b){
            x=1;
            y=0;
        }
        else{
            exgcd(b,a%b,y,x);
            y-=x*(a/b);
        }
    }
    ll CRT(ll a[],ll m[],ll n)// 数组a是余数数组,数组m是基础数数组,n是数的个数
    {
        ll M = 1;
        ll ans = 0;
        for(ll i=1; i<=n; i++)
            M *= m[i];
        for(ll i=1; i<=n; i++)
        {
            ll x, y;
            ll Mi = M / m[i];
            exgcd(Mi, m[i], x, y);
            // x为Mi关于m[i]的逆元。
            ans = (ans + Mi * x * a[i]) % M;
        }
        ans-=d;
        if(ans <=0) ans += M;
        return ans;
    }

    ACcode:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef  long long ll;
    int d;
    ll arr[10];
    ll mod[10];
    void exgcd(ll a,ll b,ll& x,ll& y){
        if(!b){x=1; y=0;}
        else{ exgcd(b,a%b,y,x); y-=x*(a/b); }
    }
    ll CRT(ll a[],ll m[],ll n)
    {
        ll M = 1;
        ll ans = 0;
        for(ll i=1; i<=n; i++)
            M *= m[i];
        for(ll i=1; i<=n; i++)
        {
            ll x, y;
            ll Mi = M / m[i];
            exgcd(Mi, m[i], x, y);
            // x为Mi关于m[i]的逆元。
            ans = (ans + Mi * x * a[i]) % M;
        }
        ans-=d;
        if(ans <=0) ans += M;
        return ans;
    }
    int main()
    {
        arr[1]=23;
        arr[2]=28;
        arr[3]=33;
        int t=1;
        while(cin>>mod[1]){
            for(ll i=2;i<=3;i++) cin>>mod[i];
            cin>>d;
            if(mod[1]==-1) break;
            printf("Case %d: the next triple peak occurs in %d days.
    ",t++,CRT(mod,arr,3));
        }
        return 0;
    }

     关于中国剩余定理还有一个是基础数不互质的情况。稍后补充。。。。

  • 相关阅读:
    Spring-Cloud之Feign
    Spring-Cloud之Ribbon原理剖析
    Spring-Cloud之Ribbon
    Spring-Cloud之Eureka
    显示列表
    顶点缓存对象(VBO)
    OpenGL观察轴
    OpenGL顶点数组
    OpenGL投影矩阵
    OpenGL变换
  • 原文地址:https://www.cnblogs.com/Accepting/p/12245729.html
Copyright © 2011-2022 走看看