zoukankan      html  css  js  c++  java
  • Euler函数与Euler定理

    欧拉函数与欧拉定理

    证明&结论

    https://www.cnblogs.com/lhm-/p/12229648.html

    欧拉定理

    容斥原理求欧拉函数(了解)

    1、如果 i % p == 0 ,那么 phi (i*p) = phi (i) * p。

    显然,与 i 互质的每一个数都与 i*p 互质。

    2、如果 i % p != 0 , 那么 phi (i*p) = phi (i) * (p-1) 。

    因为 i 与 p 互质,根据积性函数的性质,得 phi(i*p) = phi(i) * phi(p)。

    又因为 p 是质数,所以 phi(p) = p-1;

    暴力筛PHI

    int PHI(int x){
        int res=x;
        for(int i=2;i*i<=x;i++)
            if(x%i==0){
                res=res/i*(i-1);
                while(x%i==0)x/=i;
            }
        if(x^1)res=res/x*(x-1);
        return res;
    }
    

    线性筛PHI

    void PHI(int x){
        phi[1]=1;
        for(int i=2;i<=x;i++){
            if(!mindiv[i]) mindiv[i]=p[++p[0]]=i,phi[i]=i-1;
            for(int j=1;j<=p[0]&&i*p[j]<=x;j++){
                mindiv[i*p[j]]=p[j];
                if(i%p[j]==0){
                    phi[i*p[j]]=phi[i]*p[j];
                    break;
                }else phi[i*p[j]]=phi[i]*phi[p[j]];
            }
        }
    }
    

    Longge 的问题

    Description

    (gcd(i, N)(1<=i <=N))

    Solution

    枚举(n)的约数(k),令(s(k))为满足(gcd(m,n)=k,(1<=m<=n)m)的个数,则(ans=∑(k*s(k))) ((k)(n)的约数)

    因为(gcd(m,n)=k),所以(gcd(m/k,n/k)=1),于是(s(k)=phi(n/k))

    phi可以在根号的时间内求出

    #include <cstdio>
    #include <iostream>
    #define int long long
    #define M 10001000
    using namespace std;
    int n,ans;
    int PHI(int x){
        int res=x;
        for(int i=2;i*i<=x;i++){
            if(x%i==0){
                res=res/i*(i-1);
                while(x%i==0) x/=i;
            } 
        }
        if(x^1) res=res/x*(x-1);
        return res;
    }
    signed main(){
        scanf("%lld",&n);
        for(int i=1;i*i<=n;i++){
            if(n%i==0){
                ans+=i*PHI(n/i);
                if(i*i<n) ans+=(n/i)*PHI(i);
            }
        }
        printf("%lld
    ",ans);
        return 0;
    } 
    

    仪仗队

    绝了的证明——戳这里

    我的大致理解:

    要是想要被看到,必须(gcd(x,y)=1)

    然后我们把图沿着对角线割开,先分析下半部分(显然对角线上除了(2,2)你都看不到),答案乘2

    考虑第 (x) 列,有多少个(i)(x) 互素((i<x))——显然phi(i)

    #include<bits/stdc++.h>
    using namespace std;
    #define N 40005
    typedef long long ll;
    int n;
    ll phi[N],ans=3;//(2,2)(1,2)(2,1)特殊点
    int main(){
        scanf("%d",&n);
        if(n==1){
        	puts("0");
        	return 0;
    	}
    	for(int i=1;i<=n;i++)
        	phi[i]=i;
        for(int i=2;i<=n;i++)
        	if(phi[i]==i)
        		for(int j=i;j<=n;j+=i)
        			phi[j]=phi[j]/i*(i-1);
    	--n;
    	for(int i=2;i<=n;i++)
    		ans+=phi[i]*2;
    	printf("%d
    ",ans);
        return 0;
    }
    

    奇数国

    题意简化:

    ([1,product ]) 中有多少数 与 product 互质(φ[product])

    线段树维护区间内每个质因子是否出现过,由于只有60个质数,线段树维护二进制60位(状压)即可,并维护区间内的乘积,线段树单点修改,区间求和

    不开long long 见祖宗

    #include<bits/stdc++.h>
    #define int long long 
    using namespace std;
    const int mod=19961993;
    const int MAXN=1000005;
    #define ls (p<<1)
    #define rs (p<<1|1)
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    int n;
    int a,b,c;
    int mindiv[300],prime[65];
    int inv[65];
    int Fpow(int a,int b){
        int ans=1;
        while(b){
            if(b&1) ans=(ans*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ans;
    }
    void init(){
        for(int i=2;i<=281;i++){
            if(!mindiv[i]) prime[++prime[0]]=i,mindiv[i]=i;
            for(int j=1;j<=prime[0]&&i*prime[j]<=281&&prime[j]<=mindiv[i];j++)
                mindiv[i*prime[j]]=prime[j];
        }
        for(int i=1;i<=60;i++) inv[i]=Fpow(prime[i],mod-2);
    }
    int zip(int x){
        int res=0;
        for(int i=1;i<=60;i++)
            if(x%prime[i]==0) res|=(1ll<<(i-1));
        return res;
    }
    struct node{
        int l,r;
        int sum;
        int zy;
    }t[MAXN];
    void pushup(int p){
        t[p].sum=(t[ls].sum*t[rs].sum)%mod;
        t[p].zy=(t[ls].zy|t[rs].zy);
    }
    void build(int l,int r,int p){
        t[p].l=l,t[p].r=r;
        if(l==r){t[p].sum=3;t[p].zy=(1ll<<1);return;}//棰樻剰鍒濆�鍊间负3,3鏄��浜屼釜绱犳暟
        int mid=(l+r)>>1;
        build(l,mid,ls);
        build(mid+1,r,rs);
        pushup(p);
    }
    void modify(int pos,int v,int p){
        if(t[p].l==t[p].r&&t[p].l==pos){
            t[p].sum=v%mod;
            t[p].zy=zip(v);
            return;
        }
        int mid=(t[p].l+t[p].r)>>1;
        if(pos<=mid) modify(pos,v,ls);
        else modify(pos,v,rs);
        pushup(p);
    }
    int query_sum(int p,int l,int r){
        if(t[p].l==l&&t[p].r==r) return t[p].sum%mod;
        int mid=(t[p].l+t[p].r)>>1;
        if(r<=mid) return query_sum(ls,l,r)%mod;
        else if(l>mid) return query_sum(rs,l,r)%mod;
        else return (query_sum(ls,l,mid)*query_sum(rs,mid+1,r))%mod;
    }
    int query_zy(int p,int l,int r){
        if(t[p].l==l&&t[p].r==r) return t[p].zy;
        int mid=(t[p].l+t[p].r)>>1;
        if(r<=mid) return query_zy(ls,l,r);
        else if(l>mid) return query_zy(rs,l,r);
        else return query_zy(ls,l,mid)|query_zy(rs,mid+1,r);
    }
    int cal(int x,int zy){
        int res=x;
        for(int i=1;i<=60;i++)
            if(zy&(1ll<<(i-1))) 
                res=((res*inv[i]%mod)*(prime[i]-1))%mod;
        return res;
    }
    signed main(){
        n=read();
        init();
        build(1,100000,1);
        for(int i=1;i<=n;i++){
            a=read(),b=read(),c=read();
            if(!a) printf("%lld
    ",cal(query_sum(1,b,c),query_zy(1,b,c)));
            else modify(b,c,1);
        }
        return 0;
    }
    

    扩展欧拉定理

    模板

    blog

    边读入,边mod

    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define int long long
    int tmp,phi,a,m,b;
    bool flag;
    int qpow(int a,int b){
        int ans=1;
        while(b){
            if(b&1) ans=(ans*a)%m;
            a=(a*a)%m;
            b>>=1;
        }
        return ans;
    }
    signed main(){
        int i;
        char c;
        scanf("%d%d",&a,&m);
        tmp=phi=m;
        for(int i=2;i*i<=m;i++){
            if(tmp%i==0){
                phi=phi/i*(i-1);
                while(tmp%i==0) tmp/=i;
            }
        }
        if(tmp>1) phi=phi/tmp*(tmp-1);
        while(!isdigit(c=getchar())); 
        for(;isdigit(c);c=getchar()){
            b=b*10+c-'0';
            if (b>=phi){
                flag=true;
                b%=phi;
            }
        }
        if(flag) b+=phi;
        printf("%d
    ",qpow(a,b));    
        return 0;
    }
    

    上帝与集合的正确用法

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define M 10001000
    using namespace std;
    int phi[M],p[1001001],tot;
    bool not_p[M];
    int PHI(int x){
        int res=x;
        for(int i=2;i*i<=x;i++)
            if(x%i==0){
                res=res/i*(i-1);
                while(x%i==0)x/=i;
            }
        if(x^1)res=res/x*(x-1);
        return res;
    }
    int qpow(long long a,long long b,int mod){
        long long ans=1;
        while(b){
            if(b&1)ans=(ans*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ans;
    }
    int solve(int p){
        int k=PHI(p);
        if(k==1)return 0;
        return qpow(2,(solve(k)+k),p);
    }
    int main(){
        int T,mod;
        scanf("%d",&T);
        while(T--){
            scanf("%d",&mod);
            printf("%d
    ",solve(mod));
        }
        return 0;
    } 
    
  • 相关阅读:
    【周年庆】china-pub 14周年庆感恩回馈四波狂热来袭
    《Python自然语言处理》
    《大教堂与集市》
    《Redis设计与实现》
    《处理器虚拟化技术》
    《Erlang程序设计(第2版)》
    《数据化管理:洞悉零售及电子商务运营》
    《MySQL Workbench数据建模与开发》
    angular中的MVVM模式
    JavaScript函数柯里化
  • 原文地址:https://www.cnblogs.com/ke-xin/p/13531928.html
Copyright © 2011-2022 走看看