数学总结

①乘法逆元

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
#define LL long long
LL n,M;
inline LL fd(){
    LL s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
inline LL qsm(LL x,LL y){
    LL base = 1;
    while(y){
        if(y&1) base = (1ll*base%M*x%M)%M;
        x = (x%M*x%M)%M;
        y>>=1;
    }
    return base;
}
int main()
{
    freopen("P3811.in","r",stdin);
    freopen("P3811.out","w",stdout);
    n = fd(),M = fd();
    for(re LL i=1;i<=n;++i)
        printf("%lld\n",(qsm(i,M-2)%M+M)%M);
    return 0;
}
View Code

②exgcd

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
#define LL long long
LL n,M,x1,y1,x2,y2;
inline LL fd(){
    LL s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
void exgcd(LL x,LL y){
    if(!y){
        x1 = 1;y1 = 0;
        return;
    }
    exgcd(y,x%y);
    x2 = x1,y2 = y1;
    x1 = y2;
    y1 = x2-x/y*y2;
}
int main()
{
    freopen("P3811.in","r",stdin);
    freopen("P3811.out","w",stdout);
    n = fd(),M = fd();
    for(re LL i=1;i<=n;++i){
        exgcd(i,M);
        printf("%lld\n",(x1%M+M)%M);
    }
    return 0;
}
View Code

③线性递推逆元

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
#define LL int
const LL N = 3e6+5;
LL n,M,Inv[N];
inline LL fd(){
    LL s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
int main()
{
    freopen("P3811.in","r",stdin);
    freopen("P3811.out","w",stdout);
    n = fd(),M = fd();
    Inv[1] = 1;
    printf("%d\n",Inv[1]);
    for(re int i=2;i<=n;++i){
        Inv[i] = ((1ll*-Inv[M%i]*(M/i))%M+M)%M;
        printf("%d\n",Inv[i]);
    }
    return 0;
}
View Code

 ④线性筛素数

#include<iostream>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
const int M = 1e7+5;
int n,m,lx,vis[M],Q[M];
inline int fd(){
    int s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
int main()
{
    n = fd(),m = fd();
    vis[1] = 1;
    for(re int i=2;i<=n;++i){
        if(!vis[i])
            Q[++lx] = i;
        for(re int j=1;j<=lx;++j){
            if(i*Q[j] > n)
                break;
            vis[i*Q[j]] = 1;
            if(i % Q[j] == 0)
                break;
        }
    }
    while(m--){
        int x = fd();
        if(vis[x]) printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}
View Code

⑤线性筛求欧拉函数

#include<iostream>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
const int M = 1e7+5;
int n,m,lx,vis[M],Q[M];
inline int fd(){
    int s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
int main()
{
    n = fd(),m = fd();
    vis[1] = 1;
    for(re int i=2;i<=n;++i){
        if(!vis[i])
            Q[++lx] = i;
        for(re int j=1;j<=lx;++j){
            if(i*Q[j] > n)
                break;
            vis[i*Q[j]] = 1;
            if(i % Q[j] == 0)
                break;
        }
    }
    while(m--){
        int x = fd();
        if(vis[x]) printf("No\n");
        else printf("Yes\n");
    }
    return 0;
}
View Code

⑥单个求欧拉函数

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
int n;
inline int fd(){
    int s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
int phi(int x){
    int ans = x;
    for(re int i=2;i*i<=x;++i){
        if(x % i == 0){
            ans = ans - ans/i;
            while(x%i == 0)
                x /= i;
        }
    }
    if(x > 1) ans = ans - ans/x;
    return ans;
}
int main()
{
    freopen("kkk.in","r",stdin);
    freopen("kkk.out","w",stdout);
    n = fd();
    printf("%d",phi(n));
    return 0;
}
View Code

 ⑦矩阵快速幂

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
const int M = 1e9+7;
int n;
long long k;
struct JZ{
    int a[101][101];
    JZ(){memset(a,0,sizeof(a));}
    JZ operator *(const JZ &x) const{
        JZ s;
        for(re int k=1;k<=n;++k)
            for(re int i=1;i<=n;++i)
                for(re int j=1;j<=n;++j)
                    s.a[i][j] = (s.a[i][j]%M+1ll*a[i][k]*x.a[k][j]%M)%M;
        return s;
    }
}x;
inline int fd(){
    int s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
JZ qsm(JZ x,long long y){
    JZ base;
    for(re int i=1;i<=n;++i)
        base.a[i][i] = 1;
    while(y){
        if(y&1) base = base*x;
        x = x*x;
        y>>=1;
    }
    return base;
}
int main()
{
    freopen("P3390.in","r",stdin);
    freopen("P3390.out","w",stdout);
    n = fd();
    scanf("%lld",&k);
    for(re int i=1;i<=n;++i)
        for(re int j=1;j<=n;++j)
            x.a[i][j] = fd();
    x = qsm(x,k);
    for(re int i=1;i<=n;++i){
        for(re int j=1;j<=n;++j)
            printf("%d ",x.a[i][j]);
        printf("\n");
    }
    return 0;
}
View Code

 ⑧组合数递推

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
int n,c[501][501];
inline int fd(){
    int s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
int main()
{    
    freopen("k1.in","r",stdin);
    freopen("k1.out","w",stdout);
    n = fd();
    c[1][0] = c[1][1] = 1;
    for(re int i=2;i<=n;++i){
        c[i][0] = 1;
        for(re int j=1;j<=i;++j)
            c[i][j] = c[i-1][j]+c[i-1][j-1];
    }
    return 0;
}
View Code

 ⑨不定方程

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define e exit(0)
#define re register
int a,b,c,g,x,y,x1,Y1,x2,y2;
inline int fd(){
    int s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
int gcd(int x,int y){
    if(!y) return x;
    else return gcd(y,x%y);
}
void exgcd(int a,int b){
    if(!b){
        x1 = 1,Y1 = 0;
        return;
    }
    exgcd(b,a%b);
    x2 = x1,y2 = Y1;
    x1 = y2;
    Y1 = x2-a/b*y2;
}
int main()
{
    freopen("k1.in","r",stdin);
    freopen("k1.out","w",stdout);
    a = fd(),b = fd(),c = fd();
    g = gcd(a,b);
    exgcd(a,b);
    x1 = x1*(c/g),Y1 = Y1*(c/g);
    for(re int k=0;k<=100;++k){
        x = x1+k*(b/g);
        y = Y1+k*(a/g);
        printf("%d %d\n",x,y);
    }
    return 0;
}
View Code

 中国剩余定理

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define re register
#define LL long long
const LL N = 5e5+5;
LL n,M=1,x1,y1,x2,y2,a[N],b[N],ans;
inline LL fd(){
    LL s=1,t=0;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')s=-1;c=getchar();}
    while(c>='0'&&c<='9'){t=t*10+c-'0';c=getchar();}
    return s*t;
}
void exgcd(LL a, LL b){
    if(!b){
        x1 = 1,y1 = 0;
        return;
    }
    exgcd(b,a%b);
    x2 = x1,y2 = y1;
    x1 = y2;
    y1 = x2-a/b*y2;
}
int main()
{
    freopen("kkk.in","r",stdin);
    freopen("kkk.out","w",stdout);
    n = fd();
    for(re LL i=1;i<=n;++i){
        a[i] = fd(),b[i] = fd();
        M *= a[i];
    }
    for(re LL i=1;i<=n;++i){
        LL mi = M/a[i];
        exgcd(mi,a[i]);
        LL k = x1;
        ans += k*mi*b[i];
    }
    ans = ((ans%M)+M)%M;
    printf("%lld",ans);
    return 0;
}
View Code

 

posted @ 2019-11-15 16:23  xqyxqy  阅读(157)  评论(0编辑  收藏  举报