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
    评论
ACM 算法模板集 Contents 一. 常用函数与STL 二. 重要公式与定理 1. Fibonacci Number 2. Lucas Number 3. Catalan Number 4. Stirling Number(Second Kind) 5. Bell Number 6. Stirling's Approximation 7. Sum of Reciprocal Approximation 8. Young Tableau 9. 整数划分 10. 错排公式 11. 三角形内切圆半径公式 12. 三角形外接圆半径公式 13. 圆內接四边形面积公式 14. 基础数论公式 三. 大数模板,字符读入 四. 数论算法 1. Greatest Common Divisor最大公约数 2. Prime素数判断 3. Sieve Prime素数筛法 4. Module Inverse模逆元 5. Extended Euclid扩展欧几里德算法 6. Modular Linear Equation模线性方程(同余方程) 7. Chinese Remainder Theorem中国余数定理(互素于非互素) 8. Euler Function欧拉函数 9. Farey总数 9. Farey序列构造 10. Miller_Rabbin素数测试,Pollard_rho因式分解 五. 图论算法 1. 最小生成树(Kruscal算法) 2. 最小生成树(Prim算法) 3. 单源最短路径(Bellman-ford算法) 4. 单源最短路径(Dijkstra算法) 5. 全源最短路径(Folyd算法) 6. 拓扑排序 7. 网络预流和最大流 8. 网络最小费用最大流 9. 网络最大流(高度标号预流推进) 10. 最大团 11. 二分图最大匹配(匈牙利算法) 12. 带权二分图最优匹配(KM算法) 13. 强连通分量(Kosaraju算法) 14. 强连通分量(Gabow算法) 15. 无向图割边割点和双连通分量 16. 最小树形图O(N^3) 17. 最小树形图O(VE) 六. 几何算法 1. 几何模板 2. 球面上两点最短距离 3. 三点求圆心坐标 4. 三角形几个重要的点 七. 专题讨论 1. 树状数组 2. 字典树 3. 后缀树 4. 线段树 5. 并查集 6. 二叉堆 7. 逆序数(归并排序) 8. 树状DP 9. 欧拉路 10. 八数码 11. 高斯消元法 12. 字符串匹配(KMP算法) 13. 全排列,全组合 14. 二维线段树 15. 稳定婚姻匹配 16. 后缀数组 17. 左偏树 18. 标准RMQ-ST 19. 度限制最小生成树 20. 最优比率生成树(0/1分数规划) 21. 最小花费置换 22. 区间K大数 23. LCA - RMQ-ST 24. LCA – Tarjan 25. 指数型母函数 26. 指数型母函数(大数据) 27. 单词前缀树(字典树+KMP) 28. FFT(大数乘法) 29. 二分图网络最大流最小割 30. 混合图欧拉回路 31. 无源汇上下界网络流 32. 二分图最小点权覆盖 33. 带约束的轨道计数(Burnside引理) 34. 三分法求函数波峰 35. 单词计数,矩阵乘法 36. 字符串和数值hash 37. 滚动队列,前向星表示法 38. 最小点基,最小权点基

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值