C++算法竞赛常用模板-致敬爱的模板们

此文章将会持续更新,内容同步作者所学到的

代码模板

#include<bits/stdc++.h>
#define arrout(a,n) rep(i,1,n)std::cout<<a[i]<<" "
#define arrin(a,n) rep(i,1,n)std::cin>>a[i]
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define dep(i,x,n) for(int i=x;i>=n;i--)
#define erg(i,x) for(int i=head[x];i;i=e[i].nex)
#define dbg(x) std::cout<<#x<<":"<<x<<" "
#define mem(a,x) memset(a,x,sizeof a)
#define all(x) x.begin(),x.end()
#define arrall(a,n) a+1,a+1+n
#define PII std::pair<int,int>
#define m_p std::make_pair
#define u_b upper_bound
#define l_b lower_bound
#define p_b push_back
#define CD const double
#define CI const int
#define int long long
#define il inline
#define ss second
#define ff first
#define itn int
CI N=1e5+5;
signed main() {
    return 0;
}

前缀和

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,a[N],b[N];
int main() {
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
        b[i]=a[i]+b[i-1];
    }
    for (int i=1; i<=m; i++) {
        int x,y;
        cin>>x>>y;
        cout<<b[y]-b[x-1]<<endl;
    }
    return 0;
}

差分

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a[N],b[N];
int n,m,l,r,c,x;
int main() {
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
        b[i]=a[i]-a[i-1];
    }

    while (m--) {
        cin>>l>>r>>c;
        b[l]+=c;
        b[r+1]-=c;
    }
    for (int i=1; i<=n; i++) {
        x+=b[i];
        cout<<x<<" ";
    }
    return 0;
}

二分查找

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N],x,ans;
int main() {
    ios::sync_with_stdio(0);
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
    }
    cin>>x;
    int l=1,r=n;
    while (l<=r) {
        int mid=(l+r)>>1;
        if (a[mid]==x) {
            ans=mid,r=mid-1;
        } else if (a[mid]<x) {
            l=mid+1;
        } else {
            r=mid-1;
        }
    }
    if (!ans) {
        cout<<-1;
    } else {
        cout<<ans;
    }
    return 0;
}

逆序对

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],r[N];
int sum,n;
void Msort(int left,int right) {
    int mid=(right+left)/2;
    if (left==right) {
        return;
    }
    Msort(left,mid);
    Msort(mid+1,right);
    int i=left,j=mid+1,k=left;
    while (i<=mid&&j<=right) {
        if (a[i]<=a[j]) {
            r[k]=a[i];
            k++,i++;
        } else {
            r[k]=a[j];
            k++,j++;
            sum+=mid-i+1;
        }
    }
    while (i<=mid) {
        r[k]=a[i];
        k++;
        i++;
    }
    while (j<=right) {
        r[k]=a[j];
        j++;
        k++;
    }
    for (int i=left; i<=right; i++) {
        a[i]=r[i];
    }
}
int main() {
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
    }
    Msort(1,n);
    cout<<sum;
}

计数排序(桶排)

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,x,a[N];
int main() {
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>x;
        a[x]=x;
    }
    for (int i=0; i<=x; i++) {
        if (a[i]) {
            cout<<i<<' ';
            a[i]=0;
        }
    }
}

快速排序

int n,a[100005],r[100005];
void Msort(int left,int right) {
    int mid=(left+right)>>1;
    if (left==right) {
        return;
    }
    Msort(left,mid);
    Msort(mid+1,right);
    int i=left,j=mid+1,k=left;
    while (i<=mid&&j<=right) {
        if (a[i]<=a[j]) {
            r[k]=a[i];
            k++,i++;
        } else {
            r[k]=a[j];
            k++,j++;
        }
    }
    while (i<=mid) {
        r[k]=a[i];
        k++,i++;
    }
    while (j<=right) {
        r[k]=a[j];
        k++,j++;
    }
    for (int i=left; i<=right; i++) {
        a[i]=r[i];
    }
}


快速幂

int qpow(int a,int b,int q) {
    if (b==0)
        return 1%q;
    else if (b%2==1)
        return qpow(a,b-1,q)*a%q;
    else {
        int t=qpow(a,b/2,q);
        return t*t%q;
    }
}

快速幂(位运算)

int qpow(int a,int b,int q) {
    if (b==0) {
        return 1%q;
    }
    long long ans=1;
    while (b) {
        if (b&1) {
            ans=ans*a%q;
        }
        a=a*a%q;
        b>>=1;
    }
    return ans;
}

最长不下降子序列 LIS

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int ans=INT_MIN,a[N],dp[N],n;
int main() {
    cin>>n;
    for (int i=1; i<=n; i++) {
        dp[i]=1;
        cin>>a[i];
    }
    for (int i=1; i<=n; i++) {
        for (int j=1; j<=i; j++) {
            if (a[i]>a[j]) {
                dp[i]=max(dp[i],dp[j]+1);
            }
        }
    }
    for (int i=1; i<=n; i++) {
        ans=max(ans,dp[i]);
    }
    cout<<ans;
    return 0;
}

最长公共子序列 LCS

#include <bits/stdc++.h>
using namespace std;
const int N=2e3+5;
string a,b;
int len1,len2,dp[N][N];
int main() {
    cin>>a>>b;
    len1=a.size();
    len2=b.size();
    for (int i=1; i<=len1; i++) {
        for (int j=1; j<=len2; j++) {
            dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            if (a[i-1]==b[j-1]) {
                dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
            }
        }
    }
    cout<<dp[len1][len2];
    return 0;
}

对拍

#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
int main() {
    int ok=0;
    int n;
    printf("请输入你希望对拍的次数: ");
    scanf("%d",&n);
    for (int i=1; i<=n; ++i) {
        system("make.exe > make.txt");
        system("std.exe < make.txt > std.txt");
        double begin=clock();
        system("baoli.exe < make.txt > baoli.txt");
        double end=clock();

        double t=(end-begin);
        if (system("fc std.txt baoli.txt")) {
            printf("测试点#%d Wrong Answer\n",i);
        } else if (t>1000) {
            printf("测试点#%d Time Limited Exceeded 用时 %.0lfms\n",i,t);
        } else {
            printf("测试点#%d Accepted 用时%.0lfms\n",i,t);
            ok++;
        }
    }
    printf("\n");
    double res=100.0*ok/n;
    printf("共 %d 组测试数据,AC数据 %d 组。 得分%.1lf。",n,ok,res);
    Sleep(1000);
}

生成区间序列

#include <bits/stdc++.h>
using namespace std;
int random(int mod) {
    int n1,n2,n3,n4,ans;
    n1=rand();
    n2=rand();
    n3=rand();
    n4=rand();
    ans=n1*n2%mod;
    ans=ans*n3%mod;
    ans=ans*n4%mod;
    return ans;
}
int main() {
    srand((unsigned)time(0));
    int n,m;
    for (int i=1; i<=m; i++) {
        int l=random(n)+1;
        int r=random(n)+1;
        if (l>r)
            swap(l,r);
        printf("%d %d\n",l,r);
    }
    return 0;
}

生成树

#include <bits/stdc++.h>
using namespace std;
int random(int mod) {
    int n1,n2,n3,n4,ans;
    n1=rand();
    n2=rand();
    n3=rand();
    n4=rand();
    ans=n1*n2%mod;
    ans=ans*n3%mod;
    ans=ans*n4%mod;
    return ans;
}
int main() {
    srand((unsigned)time(0));
    int n,size;
    for (int i=2; i<=n; i++) {
        int fa=random(i-1)+1;
        int val=random(size)+1;
        printf("%d %d %d\n",fa,i,val);
    }
    return 0;
}

生成整数序列

#include <bits/stdc++.h>
using namespace std;
int random(int mod) {
    int n1,n2,n3,n4,ans;
    n1=rand();
    n2=rand();
    n3=rand();
    n4=rand();
    ans=n1*n2%mod;
    ans=ans*n3%mod;
    ans=ans*n4%mod;
    return ans;
}
int main() {
    srand((unsigned)time(0));
    int n_size,size,a[100005];
    int n=random(n_size)+1;
    for (int i=1; i<=n; i++) {
        a[i]=random(2*size+1)-size;
    }
    return 0;
}

随机生成图

#include <bits/stdc++.h>
using namespace std;
int n,m;
int random(int mod) {
    int n1,n2,n3,n4,ans;
    n1=rand();
    n2=rand();
    n3=rand();
    n4=rand();
    ans=n1*n2%mod;
    ans=ans*n3%mod;
    ans=ans*n4%mod;
    return ans;
}
int main() {
    srand((unsigned)time(0));
    pair<int,int> e[1000005];
    map<pair<int,int>,bool> h;
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        int fa=random(i)+1;
        e[i]=make_pair(fa,i+1);
        h[e[i]]=h[make_pair(i+1,fa)]=1;
    }
    for (int i=n; i<=m; i++) {
        int x,y,l;
        do {
            x=random(n)+1;
            y=random(n)+1;
        } while (x==y||h[make_pair(x,y)]);
        e[i]=make_pair(x,y);
        h[e[i]]=h[make_pair(y,x)]=1;
    }
    random_shuffle(e+1,e+m+1);
    for (int i=1; i<=m; i++) {
        cout<<e[i].first<<' '<<e[i].second;
    }
    return 0;
}

树状数组

单点修改,区间查询
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a[N],c[N],n,m,x;
int lowbit(int x) {
    return x&(-x);
}
void update(int x,int v) {
    for (int i=x; i<=n; i+=lowbit(i)) {
        c[i]+=v;
    }
}
int get(int l,int r) {
    int ans=0;
    for (int i=l-1; i; i-=lowbit(i)) {
        ans-=c[i];
    }
    for (int i=r; i; i-=lowbit(i)) {
        ans+=c[i];
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
        add(i,a[i]);
    }
    while (m--) {
        int k,v;
        cin>>x>>k>>v;
        if (x) {
            update(k,v);
        } else {
            cout<<get(k,v)<<"\n";
        }
    }
    return 0;
}
区间修改,单点查询
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,a[N],c[N],b[N];
int lowbit(int x) {
    return x&(-x);
}
void update(int k,int v) {
    for (int i=k; i<=n; i+=lowbit(i)) {
        c[i]+=v;
    }
}
int get(int x) {
    int ans=0;
    for (int i=x; i; i-=lowbit(i)) {
        ans+=c[i];
    }
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
        b[i]=a[i]-a[i-1];
        update(i,b[i]);
    }
    while (m--) {
        int q,x,y,k;
        cin>>q;
        if (q==1) {
            cin>>x>>y>>k;
            update(x,k);
            update(y+1,-k);
        } else {
            cin>>x;
            cout<<get(x)<<"\n";
        }
    }
    return 0;
}
区间修改,区间查询
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,a[N],b[N],c[N],maxn;
int lowbit(int a) {
    return a&(-a);
}
void update(int x,int y) {
    for (int i=x; i<=n; i+=lowbit(i)) {
        b[i]+=y;
        c[i]+=x*y;
    }
}
void range_update(int l,int r,int x) {
    update(l,x);
    update(r+1,-x);
}
int query(int x) {
    int ans=0;
    for (int i=x; i; i-=lowbit(i)) {
        ans+=(x+1)*b[i]-c[i];
    }
    return ans;
}
int range_query(int l,int r) {
    return query(r)-query(l-1);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
        update(i,a[i]-a[i-1]);
    }
    for (int i=1; i<=m; i++) {
        int q,x,y,k;
        cin>>q;
        if (q==1) {
            cin>>x>>y>>k;
            range_update(x,y,k);
        } else {
            cin>>x>>y;
            cout<<range_query(x,y)<<endl;
        }
    }
    return 0;
}

线段树

单点修改,区间查询
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int T,n,a[N<<2],s[N<<2];
void build(int k,int l,int r) {
    if (l==r) {
        s[k]=a[l];
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    s[k]=s[k<<1]+s[k<<1|1];
}
void update(int k,int l,int r,int x,int v) {
    if (x<l||r<x) {
        return;
    }
    if (l==r&&l==x) {
        s[k]+=v;
        return;
    }
    int mid=l+r>>1;
    update(k<<1,l,mid,x,v);
    update(k<<1|1,mid+1,r,x,v);
    s[k]=s[k<<1]+s[k<<1|1];
}
int query(int k,int l,int r,int x,int y) {
    if (y<l||r<x) {
        return 0;
    }
    if (x<=l&&r<=y) {
        return s[k];
    }
    int mid=l+r>>1,ans=0;
    ans=query(k<<1,l,mid,x,y);
    ans+=query(k<<1|1,mid+1,r,x,y);
    return ans;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n;
    int x,y;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
    }
    build(1,1,n);
    string q;
    while (cin>>q) {
        cin>>x>>y;
        if (q=="Add") {
            update(1,1,n,x,y);
        } else if (q=="Query") {
            cout<<query(1,1,n,x,y)<<"\n";
        }
    }
    return 0;
}
区间修改,区间查询
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,s[N],lazy[N];
char op;
void build(int k,int l,int r) {
    if (l==r) {
        s[k]=a[l];
        return;
    }
    int mid=l+r>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    s[k]=s[k<<1]+s[k<<1|1];
}
void pushdown(int k,int l,int r) {
    if (lazy[k]!=0) {
        int mid=l+r>>1;

        s[k<<1]+=(mid-l+1)*lazy[k];
        lazy[k<<1]+=lazy[k];

        s[k<<1|1]+=(r-mid)*lazy[k];
        lazy[k<<1|1]+=lazy[k];

        lazy[k]=0;
    }
}
void update(int k,int l,int r,int x,int y,int v) {
    if (y<l||r<x) {
        return;
    }
    if (x<=l&&r<=y) {
        s[k]+=(r-l+1)*v;
        lazy[k]+=v;
        return;
    }
    pushdown(k,l,r);
    int mid=l+r>>1;
    update(k<<1,l,mid,x,y,v);
    update(k<<1|1,mid+1,r,x,y,v);
    s[k]=s[k<<1]+s[k<<1|1];
}
int query(int k,int l,int r,int x,int y) {
    if (y<l||r<x) {
        return 0;
    }
    if (x<=l&&r<=y) {
        return s[k];
    }
    pushdown(k,l,r);
    int ans=0,mid=l+r>>1;
    ans+=query(k<<1,l,mid,x,y);
    ans+=query(k<<1|1,mid+1,r,x,y);
    return ans;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for (int i=1; i<=n; i++) {
        cin>>a[i];
    }
    build(1,1,n);
    while (m--) {
        int x,y,z;
        cin>>op;
        if (op=='Q') {
            cin>>x>>y;
            cout<<query(1,1,n,x,y)<<"\n";
        } else {
            cin>>x>>y>>z;
            update(1,1,n,x,y,z);
        }
    }
    return 0;
}

图的存储

const int N=1e5+5;
struct edge {
    int to,nex;
}e[N];
int head[N],tot;
void add(int x,int y) {
    e[++tot].to=y;
    e[tot].nex=head[x];
    head[x]=tot;
}

最短路

BFS最短路
#include <bits/stdc++.h>
using namespace std;
const int N=40;
int st,ed,n,vis[N],dis[N],e[N][N];
void BFS(int st,int ed) {
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    queue<int> q;
    q.push(st);
    vis[st]=1;
    dis[st]=0;
    while (!q.empty()) {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for (int i=1; i<=ed; i++) {
            if (e[x][i]==1&&vis[i]!=1) {
                q.push(i);
                vis[i]=1;
                dis[i]=dis[x]+1;
                if (i==ed) {
                    cout<<dis[i];
                    exit(0);
                }
            }
        }
    }
}
int main() {
    cin>>st>>ed>>n;
    for (int i=1; i<=n; i++) {
        int x,y;
        cin>>x>>y;
        e[x][y]=1;
        e[y][x]=1;
    }
    BFS(st,ed);
    return 0;
}
Floyd
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int n,m,st,ed,dp[N][N];
void Floyd() {
    for (int k=1; k<=n; k++) {
        for (int i=1; i<=n; i++) {
            for (int j=1; j<=n; j++) {
                if (dp[i][k]+dp[k][j]<dp[i][j]) {
                    dp[i][j]=dp[i][k]+dp[k][j];
                }
            }
        }
    }
}
int main() {
    cin>>n>>m;
    memset(dp,0x7f,sizeof(dp));
    for (int i=1,x,y; i<=m; i++) {
        cin>>x>>y;
        dp[y][x]=dp[x][y]=1;
    }
    cin>>st>>ed;
    Floyd();
    cout<<dp[st][ed];
    return 0;
}
Dijkstra
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,st,ed,head[N],dis[N],tot;
struct node {
    int nex,to,data;
} a[N];
void add(int x,int y,int z) {
    a[++tot].data=z;
    a[tot].to=y;
    a[tot].nex=head[x];
    head[x]=tot;
}
struct edge {
    int to,data;
    bool operator<(const edge& b)const {
        return data>b.data;
    }
};
void Dijkstra(int st) {
    memset(dis,0x3f,sizeof(dis));
    dis[st]=0;
    priority_queue<edge>q;
    q.push(edge({ st,0 }));
    while (!q.empty()) {
        edge x=q.top();
        q.pop();
        int to=x.to;
        int data=x.data;
        if (data!=dis[to]) {
            continue;
        }
        for (int i=head[to]; i; i=a[i].nex) {
            int v=a[i].to;
            int w=a[i].data;
            if (dis[to]+w<dis[v]) {
                dis[v]=dis[to]+w;
                q.push(edge({ v,dis[v] }));
            }
        }
    }
}
int main() {
    cin>>n>>m>>st>>ed;
    for (int i=1,x,y,z; i<=m; i++) {
        cin>>x>>y>>z;
        add(x,y,z);
        add(y,x,z);
    }
    Dijkstra(st);
    if (dis[ed]!=0x3f3f3f3f) {
        cout<<dis[ed];
    } else {
        cout<<-1;
    }
    return 0;
}
/*
5 8 1 2
0 2 5
0 4 6
0 5 4
1 4 1
1 5 3
2 3 2
2 4 9
4 5 7
*/
SPFA
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,st,ed,tot;
int head[N],dis[N],cnt[N],vis[N];
struct node {
    int to,data,nex;
} e[N];
void add(int x,int y,int z) {
    e[++tot].to=y;
    e[tot].data=z;
    e[tot].nex=head[x];
    head[x]=tot;
}
void SPFA(int st) {
    queue<int>q;
    dis[st]=0;
    q.push(st);
    while (!q.empty()) {
        int x=q.front();
        q.pop();
        vis[x]=0;
        for (int i=head[x]; i; i=e[i].nex) {
            int y=e[i].to;
            int z=e[i].data;
            if (dis[y]>dis[x]+z) {
                dis[y]=dis[x]+z;
                cnt[y]=cnt[x]+1;
                if (cnt[y]>n) {
                    cout<<"有负环"<<endl;
                    return;
                }
                if (!vis[y]) {
                    vis[y]=1;
                    q.push(y);
                }
            }
        }
    }
}
int main() {
    cin>>n>>m>>st>>ed;
    memset(dis,0x3f,sizeof(dis));
    for (int i=1,x,y,z; i<=m; i++) {
        cin>>x>>y>>z;
        add(x,y,z);
    }
    SPFA(st);
    if (dis[ed]!=0x3f3f3f3f) {
        cout<<dis[ed];
    } else {
        cout<<-1;
    }
    return 0;
}
/*
5 8 1 2
0 2 5
0 4 6
0 5 4
1 4 1
1 5 3
2 3 2
2 4 9
4 5 7
*/

最小生成树

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct edge {
    int from,to,data;
    bool operator<(const edge b) const {
        return data<b.data;
    }
} e[N];
int n,f[N],ans;
int find(int x) {
    return x==f[x]?x:f[x]=find(f[x]);
}
void add(int x,int y) {
    if (find(x)!=find(y)) {
        f[find(x)]=find(y);
    }
}
int main() {
    cin>>n;
    for (int i=1; i<=n; i++) {
        f[i]=i;
        for (int j=1; j<=n; j++) {
            int x;
            cin>>x;
            e[++f[0]]=(edge){i,j,x};
        }
    }
    sort(e+1,e+1+f[0]);
    int cnt=0;
    for (int i=1; i<=f[0]; i++) {
        if (find(e[i].from)!=find(e[i].to)) {
            add(e[i].from,e[i].to);
            ans+=e[i].data;
            if (++cnt==n-1) {
                break;
            }
        }
    }
    cout<<ans;
    return 0;
}

数论

线性筛
int p[N],vis[N];
void prime() {
    for (int i=2; i<=n; i++) {
        if (!vis[i]) {
            p[++p[0]]=i;
        }
        for (int j=1; j<=p[0]&&p[j]*i<=n; j++) {
            vis[p[j]*i]=1;
            if (i%p[j]==0) {
                break;
            }
        }
    }
}
唯一分解定理(质因数分解)
int p[N],vis[N];
void prime(int n) {
    for (int i=2; i*i<=n; i++) {
        if (c%i==0) {
            p[++p[0]]=i,vis[p[0]]=0;
            while (c%i==0) {
                c/=i,vis[p[0]]++;
            }
        }
    }
    if (c>1) {
        p[++p[0]]=c,a[p[0]]=1;
    }
}
CRT
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,x,y,ans;
int a[24],m[24];
int exgcd(int a,int b,int& x,int& y) {
    if (b==0) {
        x=1,y=0;
        return a;
    }
    int ret=exgcd(b,a%b,x,y);
    int t=x;
    x=y,y=t-(a/b)*y;
    return ret;
}

int CRT(int a[],int m[],int n) {
    int ans=0,M=1;
    for (int i=1; i<=n; i++)
        M*=m[i];
    for (int i=1; i<=n; i++) {
        int Mi=M/m[i];
        exgcd(Mi,m[i],x,y);
        ans=(ans+x*a[i]*Mi)%M;
    }
    if (ans<0) {
        ans+=M;
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(0);
    cin>>n;
    for (int i=1; i<=n; i++) {
        cin>>m[i]>>a[i];
    }
    ans=CRT(a,m,n);
    cout<<ans;
    return 0;
}
GCD
int gcd(int a,int b) {
    if (!b) {
        return a;
    }
    return gcd(b,a%b);
}
欧拉函数序列
int phi[1000005];
void euler(int n) {
    for (int i=1; i<=n; i++) {
        phi[i]=i;
    }
    phi[1]=1;
    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);
            }
        }
    }
}
欧拉函数值
int euler(int n) {
    int ans=n;
    for (int i=1; i*i<=n; i++) {
        if (n%i==0) {
            ans=ans/i*(i-1);
            while (n%i==0) {
                n/=i;
            }
        }
    }
    if (n>1) {
        ans-=ans/n;
    }
    return ans;
}
矩阵乘法
struct matrix {
    int mat[N][N];
    matrix() {
        memset(mat,0,sizeof mat);
    }
    matrix operator*(const matrix& b)const {
        matrix ans;
        for (int i=1; i<=N; i++) {
            for (int j=1; j<=N; j++) {
                for (int k=1; k<=N; k++) {
                    ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*b.mat[k][j]%MOD)%MOD;
                }
            }
        }
        return ans;
    }
};
矩阵快速幂
struct matrix {
    int mat[N][N];
    matrix() {
        memset(mat,0,sizeof mat);
    }
    matrix operator*(const matrix& b)const {
        matrix ans;
        for (int i=1; i<=N; i++) {
            for (int j=1; j<=N; j++) {
                for (int k=1; k<=N; k++) {
                    ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*b.mat[k][j]%MOD)%MOD;
                }
            }
        }
        return ans;
    }
};
matrix qpow(matrix a,int b){
	matrix ans;
	for(int i=1;i<=N;i++){
		ans.mat[i][i]=1;
	}
	while(b){
		if(b&1){
			ans=ans*a;
		}
		a=a*a;
		b>>=1;
	}
}
组合数(Lucas定理)
int qpow(int a,int b) {
    int ans=1;
    while (b) {
        if (b&1) {
            ans=ans*a%MOD;
        }
        a=a*a%MOD;
        b>>=1;
    }
    return ans;
}
int C(int n,int m) {
    if (m<0) {
        return 0;
    }
    if (n<m) {
        return 0;
    }
    if (m>n-m) {
        m=n-m;
    }
    int up=1,down=1;
    for (int i=0; i<m; i++) {
        up=up*(n-i)%MOD;
        down=down*(i+1)%MOD;
    }
    return qpow(down,MOD-2)*up;
}
int Lucas(int n,int m) {
	if (m==0) {
		return 1;
	} else {
		return Lucas(n/MOD,m/MOD)%MOD*C(n%MOD,m%MOD)%MOD;
	}
}
组合数(预处理阶乘+逆元)
int fac[N],inv[N];
int qpow(int a,int b) {
	int ans=1;
	while (b) {
		if (b&1) {
			ans=ans*ans%MOD;
		}
		a=a*a%MOD;
		b>>=1;
	}
	return ans;
}
void pre() {
	fac[0]=inv[0]=1;
	for (int i=1; i<=N; i++) {
		fac[i]=fac[i-1]*i%MOD;
	}
	inv[N]=qpow(fac[N],MOD-2);
	for (int i=N-1; i>=0; i--) {
		inv[i]=inv[i+1]*(i+1)%MOD;
	}
}
int C(int n,int m) {
	return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值