zoukankan      html  css  js  c++  java
  • 《数论整理一》

    前言:数论很难也很有意思,慢慢回顾和慢慢学,记录自己的感悟和理解。

    keeping going !

    欧拉函数:

    假定phi(x)为x的欧拉函数,这个函数表示的就是1~i中和i互质的数。例phi(1) = 1,phi(2) = 1,phi(8) = 4。

    欧拉函数的通式$phi(x) = x * prod_{x = 1}^{tot} (1-frac{1}{pi})$//tot为x的质因子的个数,注意是质因子。

    那么我们对这个式子化简一下:$phi(x) = x * prod_{x = 1}^{tot} (frac{pi-1}{pi})$

    那么就可以o(sqrt(n))得到一个数的欧拉函数。

    代码思想:因为都是质因子,那么我们做质因子分解即可。

    然后边分解边乘。

    LL eular(LL x)
    {
        LL ans = x;
        int m = sqrt(x);
        for(rg int i = 2;i <= m;++i)
        {
            if(x%i == 0)
            {
                ans = ans/i*(i-1);//注意先除后乘,防止爆精度
                while(x/i == 0) x /= i;
            }
        }
        if(x > 1) ans = ans/x*(x-1);
        return ans;
    }
    View Code

     欧拉函数求和通式:定义$s[i] = sum_{j = 1}^{i} phi[j]$

    可由杜教筛得 $s[i] = frac{i*(i+1)}{2} - sum_{j = 2}^{i} s[frac{i}{j}]$

    欧拉定理:

     当满足a与m互质时,有$a^{b} mod (m) equiv a^{b mod phi[m]} mod (m)$

    欧拉降幂:

    由欧拉定理,我们可以得到欧拉降幂的公式。

    显然用的条件是在次数过大时。次数小直接快速幂就可以了。

    当$gcd(a,m) = 1  , a^{b} mod (m) equiv a^{bmod(phi[m])} mod (m)$

    当$gcd(a,m) != 1 , b >= phi[m] , a^{b} mod (m) equiv a^{bmod(phi[m]) + phi[m]} mod (m)$

    其他直接快速幂。

    模板题:洛谷P5091 【模板】扩展欧拉定理

    这里我们直接去判断b 是否 > 最大的模数就行。

    LL eular(LL x)
    {
        LL ans = x,m = sqrt(x);
        for(rg LL i = 2;i <= m;++i)
        {
            if(x%i == 0)
            {
                ans = ans/i*(i-1);
                while(x%i == 0) x /= i;
            }
        }
        if(x > 1) ans = ans/x*(x-1);
        return ans;
    }
    LL quick_mi(LL a,LL b,LL p)
    {
        LL re = 1;
        while(b)
        {
            if(b&1) re = re*a%p;
            a = a*a%p;
            b >>= 1;
        }
        return re;
    }
    int main()
    {
        LL a;a = read();
        LL m;m = read();
        string s;cin >> s;
        int len = s.size();
        LL ans;
        if(len <= 8)
        {
            LL ma = 0;
            for(rg int i = 0;i < len;++i) ma = ma*10+s[i]-'0';
            ans = quick_mi(a,ma,m);
        }
        else
        {
            LL phi = eular(m),ma = 0;
            if(__gcd(a,m) == 1)//底数和模数互质
            {
                for(rg int i = 0;i < len;++i) ma = (ma*10+s[i]-'0')%phi;
                ans = quick_mi(a,ma,m);
            }
            else
            {
                for(rg int i = 0;i < len;++i) ma = (ma*10+s[i]-'0')%phi;
                ans = quick_mi(a,ma+phi,m);
            }
        }
        printf("%lld
    ",ans);
        system("pause");    
    }
    View Code

    威尔逊定理:

    当p为质数时有$(p-1)! equiv -1 mod(p)$

    也可得$(p-2)! equiv 1 mod(p)$

    即(p - 1)! mod p = p - 1 

    这里的变形推导没推出来。太菜了~

     这里介绍下同余变换法则:

    $a equiv b mod (m)$表示a-b可以整除m,也就是可以推得下面的第二个

    $a equiv b mod (m) ightarrow (a+b) equiv 0 mod (m)$

    $a equiv b mod (m) ightarrow (a-b) equiv 0 mod (m)$

    $a equiv b mod (m) ightarrow a * c equiv b * c mod (m)$

    $a equiv b mod (m) ightarrow a^{n} equiv b^{n} mod (m)$

    多个式子:如果a ≡ x(mod d),b ≡ m(mod d),则

    a+b ≡ x+m (mod d)
    a-b ≡ x-m (mod d)
    a*b ≡ x*m (mod d )
    其实和前面单个的变换一样,因为b和m对d取模后就是一样的数了
     
    这题就是威尔逊定理的应用。
    由令3k+6 = p-1.
    那么求的式子就变成了$s[n] = sum_{k = 1}^{n}[frac{(p-1)!+1}{p} - frac{(p-1)!}{p}]$
    那么前面那个分数就是 $frac{(p-1)!+1}{p}$
    那么由威尔逊定理可得$(p-1)! equiv -1 mod(p) ightarrow (p-1)!+1 equiv 0 mod(p)$
    也就是表示当p为质数时,(p-1)!+1 整除 p。
    那么(p-1)!不整除p。
    那么由于[]操作,后面的那个数显然比前面的少1。因为1显然<p。所以不可能降过1.
    此时答案就是[1] = 1。
    当p不为质数时,(p-1)!+1 不整除 p.
    因为威尔逊定理是一个充要条件:那么就有$frac{(p-1)!+1}{p}$和$frac{(p-1)!}{p}$的整数部分相同。
    可以理解为因为(p-1)!+1 和 (p-1)!都不整除p,那么他们都是p的k倍。然后+1不凑成整数,无法增加1倍。
    所以这里的答案就是[0] = 0
     提交莫名CE..
    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<string,int> pii;
    const int N = 1e6+5;
    const int M = 2e5+5;
    const LL Mod = 1e9+7;
    #define rg register
    #define pi acos(-1)
    #define INF 1e9
    #define CT0 cin.tie(0),cout.tie(0)
    #define IO ios::sync_with_stdio(false)
    #define dbg(ax) cout << "now this num is " << ax << endl;
    namespace FASTIO{
        inline LL read(){
            LL x = 0,f = 1;char c = getchar();
            while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
            while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
            return x*f;
        }
        void print(int x){
            if(x < 0){x = -x;putchar('-');}
            if(x > 9) print(x/10);
            putchar(x%10+'0');
        }
    }
    using namespace FASTIO;
    void FRE(){/*freopen("data1.in","r",stdin);
    freopen("data1.out","w",stdout);*/}
    
    int f[N];
    bool check(int x)
    {
        if(x < 2) return false;
        int m = sqrt(x);
        for(rg int i = 2;i <= m;++i) if(x%i == 0) return false;
        return true;
    }
    void init()
    {
        for(rg int i = 1;i < N;++i)
        {
            int x = 3*i+7;
            if(check(x)) f[i] = f[i-1]+1;
            else f[i] = f[i-1]+0;
        }
    }
    int main()
    {
        init();
        int ca;ca = read();
        while(ca--)
        {
            int n;n = read();
            printf("%d
    ",f[n]);
        }
        system("pause");    
    }
    View Code
  • 相关阅读:
    『Linux学习笔记』0. 在Windows中运行Linux内核(Ubuntu)
    『Linux学习笔记』10. 文本编辑器
    『Linux学习笔记』9. 进程
    九种乱码解决办法(非原创)
    Eclipse中10个最有用的快捷键组合
    MVC(Model View Controller)框架
    ognl表达式
    统计一段文字中数组、中文、英文字母、空格以及其他特殊字符出现的次数
    java基础知识4
    java基础知识3
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/13636032.html
Copyright © 2011-2022 走看看