数论小结+代码实现

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<map>
#include<cstdio>
using namespace std;
typedef long long LL;
inline int input() {
    char c=getchar();int x=0,a=1;
    for(;c<'0'||c>'9';c=getchar())
        if(c=='-') a=-1;
    for(;c>='0'&&c<='9';c=getchar())
        x=(x<<1)+(x<<3)+c-'0';
    return x*a;
}
namespace Fast__Pow {
    int n,k;    //n^k
    void read(){
        n=input();
        k=input();
        return;
    }
    int Fast_Pow(int n,int k) {
        int ret=1,a=n;
        while(k){
            if(k&1) ret*=a;
            a=a*a;k>>=1;
        }
        return ret;
    }
    void solve() {
        read();
        printf("%d",Fast_Pow(n,k));
        return;
    }
}
namespace matrix { //矩乘+快速幂; 
    const int maxn=110;
    int n,k;
    struct Matrix {
        int a[maxn][maxn];
        void clear() {
            memset(a,0,sizeof(a));
            return;
        }
        Matrix() {
            this->clear();
        }
        Matrix operator * (const Matrix &c)const {
            Matrix Ans;//a矩阵 和c矩阵相乘  答案放到Ans里
            for(int k=0;k<n;k++)
                for(int i=0;i<n;i++)
                    for(int j=0;j<n;j++)
                        Ans.a[i][j]+=a[i][k]*c.a[k][j];
            return Ans;
        }
        void Print() {
            for(int i=0;i<n;i++) {
                for(int j=0;j<n;j++)
                    printf("%d ",a[i][j]);
                printf("\n");
            }
        }
    }A;
    Matrix poow(Matrix A,int k){//矩阵A的k次方
        Matrix ret=A,t=A;
        for(k--;k;k>>=1,t=t*t)//k-- 是因为 定义时ret=A
            if(k&1) ret=ret*t;
        return ret;
    }
    void read(){
        n=input();k=input();
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                A.a[i][j]=input();
        return;
    }
    void solve() {
        read();
        A=poow(A,k);
        A.Print();
        return;
    }
}
namespace Prime{ //素数; 
    const int maxn=1010;
    int prime[maxn],n,tot=0;
    bool vis[maxn];
    bool is_prime(int x) {
        int k=sqrt(x+0.5);
        for(int i=2;i<=k;i++)
            if(x%i==0) return false;
        return true;
    }
    void read() {
        n=input();
        return;
    }
    void GetPrime(){//筛 1-n 的所有素数
        for(int i=2;i<=n;i++){
            if(vis[i]==false) prime[++tot]=i;
            for(int j=1;j<=tot&&i*prime[j]<=n;j++){
                vis[i*prime[j]]=true;
                if(i%prime[j]==0) break;
            }
        }
        return;
    }
    void solve(){
        read();
        GetPrime();
        for(int i=1;i<=tot;i++)
            printf("%d ",prime[i]);
        return;
    }
}
//a/b Mod P = a * inv(b,p); 前提是b、p互质
namespace Phi {//求单个数的欧拉函数
    int phi(int x){
    int ret=1;
    for(int i=2;i*i<=x;i++){
        if(x%i==0){
            ret*=i-1;x/=i;
            while(x%i==0) ret*=i,x/=i;
        }
    }
    if(x>1) ret*=x-1;
    return ret;
    }
}
namespace Pre_Phi {//欧拉函数线性筛法
    //p为质数的时候
    //1. phi(p)=p-1   不懂的用屁股想,千万别用脑子
    //2.if(i%p==0) 那么 phi(i*p) = p * phi(i);
    //3.if(i%p!=0) phi(i * p)=phi(i) * (p-1)   i mod p 不为0且p为质数, 所以i与p互质,
    // 那么根据欧拉函数的积性phi(i * p)=phi(i) * phi(p) 其中phi(p)=p-1即第一条性质
    const int MAXN = 50005;
    int phi[50005],prime[50005],tot,ans;
    bool is_prime[50005];
    void Set(){
        phi[1]=1;//必须写在函数里 
        memset(is_prime,true,sizeof(is_prime));
    }
    void pre_phi(){
        for(int i=2;i<=MAXN;i++){
            if(is_prime[i]){
                prime[++tot]=i;
                phi[i]=i-1;
            }
            for(int j=1;j<=tot&&i*prime[j]<=MAXN;j++){
                is_prime[i*prime[j]]=false;
                if(i%prime[j]==0) phi[i*prime[j]]=prime[j]*phi[i];
                else phi[i*prime[j]]=(prime[j]-1)*phi[i];
            }
        }
    }
}
namespace Get_Inv {
    //a^phi(p)≡1 (Mod) p
    //对于任意互质的a,p 恒成立
    //不互质 不存在
    //ab ≡ 1(mod p)
    //若 a 与 p 互质, 则?定存在?个正整数解 b, 满? b < p.
    //若 a 与 p 不互质, 则?定不存在正整数解 b.
    int a,p;
    int inv(int a,int p) {//求解a在Mod P意义下的逆元
        return Fast__Pow::Fast_Pow(a,Phi::phi(p)-1);
    }
}
namespace Pre_Inv {//线性求逆元  1->N Mod P 意义下的所有数对应的逆元值
    //递推式:inv[i] = (P - P/i)*inv[P%i]%P;-----证明略
    //inv[i]表示i在Mod P 意义下的逆元  
    void pre_inv(){
        int p,n,inv[1000001]; inv[1]=1;
        cin>>n>>p;
        for(int i=2;i<=n;i++) inv[i]=(p-p/i)*inv[p%i]%p;
    }
}
//(完全)积性函数  f(ab)=f(a)*f(b) 完全积形函数不要求gcd(a,b)==1
//常见的数论函数:
//1: 对于任意正整数 x, 函数值恒为 1.
//e: 对于正整数 x, 若 x = 1, 则函数值为 1, 否则为 0.
//n: 对于任意正整数 x, 函数值恒为 x.
//以上为完全积性函数.
//d: 对于正整数 x, 函数值为它的正因子个数.
//φ: 对于正整数 x, 函数值为小于等于 x 且与 x 互质的正整数的个数.
//μ: 对于正整数 x, 设正整数 x 的质因子分解 x = ∏k i=1 ai^pi, 若其中存
//在 pi ≥ 2, 则函数值为 0, 否则为 (-1)^k. 特殊的,μ(1) = 1.
//以上为积性函数
//常见的狄利克雷卷积:
//φ*1=n(*是狄利克雷卷积的意思)
//μ*1=e
//莫比乌斯反演定理:如果有两个数论函数 f,F, 满足:F=f*1 那么:f=F*μ
//BZOJ 1101
/*#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define LL long long
#define MAXN 50010
LL prime[MAXN],mu[MAXN];
int tot=0,not_prime[MAXN],n,m,k,T;
void Liner_Shaker(){//线性筛miu函数
    mu[1]=1;
    for(int i=2;i<=50000;i++){
        if(!not_prime[i]){
            mu[i]=-1;
            prime[++tot]=i;
        }
        for(int j=1;j<=tot&&i*prime[j]<=50000;j++){
            not_prime[i*prime[j]]=true;
            if(i%prime[j]==0){
                mu[i*prime[j]]=0; break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=50000;i++) mu[i]=mu[i]+mu[i-1];
}
LL Calc(int n,int m,int k){
    LL ret=0; int last;
    n/=k;m/=k;
    for(int i=1;i<=m&&i<=n;i=last+1){
        last=min(n/(n/i),m/(m/i));
        ret+=(mu[last]-mu[i-1])*(m/i)*(n/i);
    }
    return ret;
}
int main(){
    freopen("data.out","r",stdin);
    freopen("ceshi.out","w",stdout);
    scanf("%d",&T);
    Liner_Shaker();
    while(T--){
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        printf("%lld\n",Calc(n,m,k));
    }
    return 0;
}*/
namespace Gcd_ {
    int gcd(int a,int b){
        if(!b) return a;
        else return gcd(b,a%b);
    }
    int ExGcd(int a,int b,int &x,int &y){
        //求解ax+by=gcd(a,b)
        //k·ax + k·by=k·gcd(a,b)
        //算法满足 求得的 |x|+|y| 最小
        if(b==0){ x=1;y=0;return a; }
        int ans=ExGcd(b,a%b,x,y);
        int temp=x; x=y; y=temp-a/b*y;
        return ans;//ans 是顺便求出了gcd(a,b)
    }
}
namespace BS_GS {
    //求解形如x^y≡z(Mod P) 中y的取值的算法
    //算法思想很好
    //不妨令y=km+i,m是一个常量
    //x^(km+i)≡z(Mod P)
    //x^i≡z*x^(-km)(Mod P)
    //Baby Step:将x^i预处理出来+++Map
    //Gaint Step:枚举k在Map查找是否存在 z*x^(-km)
    map<LL,int> Mp;
    LL Fast_Pow_Mod(LL a,LL b,LL p){
        LL ret=1;
        while(b){
            if(b&1) ret=(ret*a)%p;
            a=(a*a)%p; b>>=1;
        }
        return ret;
    }
    LL BSGS(LL x,LL z,LL P){
        Mp.clear(); x%=P;
        if(x==0&&z==0) return 1;
        if(x==0&&z!=0) printf("Orz");
        LL m=ceil(sqrt(P));Mp[1]=m+1;
        LL ans=1;
        for(int i=1;i<m;i++){//x^i 预处理
            ans=(ans*x)%P;
            if(!Mp[ans]) Mp[ans]=i;
        }
        LL temp=1,tmp=Fast_Pow_Mod(x,P-m-1,P);
        for(LL k=0;k<m;k++){
            int i=Mp[(z*temp)%P];
            if(i){
                if(i==m+1) i=0;
                return k*m+i;
            }
            temp=(temp*tmp)%P;
        }
        printf("Orz!");
    }
}
//BSGS  完结
namespace Mobius{
    //莫比乌斯函数μ(d)的定义如下 
    //(1)若d=1,那么μ(d)=1 
    //(2)若d=p1p2…pk(p1…pk均为互异质数),那么μ(d)=(-1)^k 
    //(3)其他情况下,μ(d)=0
    //假设当前从μ(i),μ(pt)转移到μ(i·pt),有以下几个式子便于我们筛出莫比乌斯函数: 
    //1、如果pt是在ipt中第一次出现的话(也就是pt不整除i),则μ(i·pt)=-μ(i) 
    //2、如果pt不是在ipt中第一次出现的话(也就是pt整除i),则μ(i·pt)=0
    const int MAXN = 50005;
    void Get_Mobius(){
        int tot=0,miu[MAXN],prime[MAXN];
        bool Is_Prime[MAXN];
        memset(Is_Prime,true,sizeof Is_Prime );
        miu[1]=1;
        for(int i=2;i<=MAXN;i++){
            if(Is_Prime[i]) prime[++tot]=i,miu[i]=-1;
            for(int j=1;j<=tot&&i*prime[j]<=MAXN;j++){
                Is_Prime[i*prime[j]]=false;
                if(i%prime[j]==0){
                    miu[i*prime[j]]=0;
                    break;
                }
                else miu[i*prime[j]]=(-1)*miu[i];
            }
        }
    }
}
int main() {    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七情六欲·

学生党不容易~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值