1. 程式人生 > >模板整理計劃

模板整理計劃

“是時候了”
“好”
“我來了” “NOIp”

這裡寫圖片描述

全排列

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (100)
int n;
int num[MAXN];
bool vis[MAXN];

void print()
{
    for(int i = 1; i <= n; ++ i)
        printf("%d ", num[i]);
    cout
<< '\n'; } void dfs(int x) { if(x > n) { print(); return; } for(int i = 1; i <= n; ++ i) { if(!vis[i]) { num[x] = i; vis[i] = 1; dfs(x+1); vis[i] = 0; } } } int main() { cin
>> n; dfs(1); return 0; }

選數半排列

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (100)
int n, k;
int num[MAXN], ans[MAXN];

void print()
{
    for(int i = 1; i <= k; ++ i)
        printf("%d ", ans[i]);
    cout
<< '\n'; } void dfs(int x, int last) { if(x > k) { print(); return; } for(int i = last+1; i <= n; ++ i) { ans[x] = num[i]; dfs(x+1, i); } } int main() { cin >> n >> k; for(int i = 1; i <= n; ++ i) scanf("%d", &num[i]); dfs(1,0); return 0; }

這裡寫圖片描述

DFS子集列舉

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (100)
int n;
bool vis[MAXN];

void print()
{
    for(int i = 1; i <= n; ++ i)
        printf("%d ", vis[i]);
    cout << '\n';
}

void dfs(int x)
{
    if(x > n)
    {
        print();
        return;
    }
    vis[x] = 0;
    dfs(x+1);
    vis[x] = 1;
    dfs(x+1);
    vis[x] = 0;
}

int main()
{
    cin >> n;
    dfs(1);
    return 0;
}

二進位制子集列舉

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
    int n;
    cin >> n;
    for(int s = 0; s < (1<<n); ++ s)
    {
        for(int j = n-1; j >= 0; -- j)
            cout << (bool)(s&(1<<j)) << " ";
        cout << '\n';
    }
    return 0;
}

這裡寫圖片描述

gcd

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

int gcd(int a, int b)
{
    if(!b) return a;
    return gcd(b,a%b);
}

int main()
{
    int a, b;
    cin >> a >> b;
    cout << gcd(max(a,b),min(a,b));
    return 0;
}

exgcd

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

int exgcd(int a, int b, int &x, int &y)
{
    if(!b) 
    {
        x = 1; y = 0;
        return a;
    }
    int ans = gcd(b,a%b,x,y);
    int t = x;
    x = y;
    y = t-a/b*y;
    return ans;
}

int main()
{
    int a, b, x, y;
    cin >> a >> b;
    cout << gcd(max(a,b),min(a,b),x,y) << " " << x << " " < y << '\n';
    return 0;
}

這裡寫圖片描述

埃氏篩法

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (100000)
bool vis[MAXN];

int main()
{
    int n;
    cin >> n;
    for(int i = 2; i <= n; ++ i)
        if(!vis[i])
            for(int j = i+i; j <= n; j += i)
                vis[j] = 1;
    for(int i = 2; i <= n; ++ i)
        if(!vis[i])
            printf("%d ", i);
    printf("\n");
    return 0;
} 

尤拉篩法-線性篩

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (100000)
bool vis[MAXN];
int prime[MAXN];

int main()
{
    int n, cnt = 0;
    cin >> n;

    fill(vis+1, vis+n+1, 1);
    for(int i = 2; i <= n; ++ i)
    {
        if(vis[i]) prime[++cnt] = i;
        for(int j = 1; j <= cnt && prime[j]*i <= n; ++ j)
        {
            vis[prime[j]*i] = 0;
            if(i%prime[j] == 0) break;
        }
    }

    for(int i = 1; i <= cnt; ++ i)
        printf("%d ", prime[i]);
    printf("\n");
    return 0;
} 

這裡寫圖片描述

快速冪(非遞迴)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long LL;

LL ksm(LL a, LL p, LL k)
{
    LL ans = 1;
    for(; p; p >>= 1, a = ((a%k)*(a%k))%k)
        if(p&1)
            ans = ((ans%k)*(a%k))%k;
    return ans%k;
}

int main()
{
    LL a, b, c;
    cin >> a >> b >> c;
    printf("%lld^%lld mod %lld=%lld\n",a, b, c, ksm(a,b,c));
    return 0;
}

這裡寫圖片描述

暴力LCA(帶DFS+邊權)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAX_V (500000)
#define MAX_E (MAX_V)
int V, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], deep[MAX_V], fa[MAX_V], dis[MAX_V];
struct edge{
    int from, to, cost;
}es[MAX_E<<1];

void build(int ff, int tt, int dd)
{
    es[++tot] = (edge){ff,tt,dd};
    nxt[tot] = first[ff];
    first[ff] = tot;
}

void dfs(int x, int f)
{
    fa[x] = f;
    deep[x] = deep[f]+1;
    for(int i = first[x]; i != -1; i = nxt[i])
    {
        int v = es[i].to;
        if(v == f) continue;
        dis[v] = es[i].cost;
        dfs(v,x);
    }
}

int lca(int x, int y)
{
    int ans = 0;
    if(deep[x] > deep[y]) swap(x,y);
    while(deep[y] != deep[x])
    {
        ans += dis[y];
        y = fa[y];
    }
    while(x != y)
    {
        ans += dis[x];
        x = fa[x];
        ans += dis[y];
        y = fa[y];
    }
    return ans;
}

int main()
{
    cin >> V;
    memset(first,-1,sizeof(first));
    for(int i = 1; i < V; ++ i)
    {
        int f, t, d;
        scanf("%d%d%d", &f, &t, &d);
        build(f,t,d); build(t,f,d);
    }
    deep[1] = 0; dis[1] = 0;
    dfs(1,1);
    int Q;
    cin >> Q;
    while(Q --)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", lca(x,y));
    }
    return 0;
}

這裡寫圖片描述

並查集

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (10010)
int fa[MAXN];

int find(int x)
{
    int t, r = x;
    while(r != fa[r]) r = fa[r];
    while(x != r) {t=fa[x];fa[x]=r;x=t;}
    return r;
}

void lianjie(int x, int y)
{
    int fx = find(x), fy = find(y);
    if(fx != fy) fa[fx] = fy;
}

void check(int x, int y)
{
    int fx = find(x), fy = find(y);
    if(fx != fy) puts("N"); 
    else puts("Y");
}

int main()
{
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; ++ i) fa[i] = i;
    for(int i = 1; i <= m; ++ i)
    {
        int t, x, y;
        scanf("%d%d%d", &t, &x, &y);
        if(t == 1) lianjie(x,y);
        else check(x,y);
    }
    return 0;
}

這裡寫圖片描述

最小生成樹Kruskal

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define MAX_V (5050)
#define MAX_E (200200)
int V, E;
int fa[MAX_V];
struct edge{
    int from, to, cost;
}es[MAX_E];

bool cmp(edge a, edge b) {return a.cost < b.cost;}

int find(int x)
{
    int t, r = x;
    while(r != fa[r]) r = fa[r];
    while(x != r){t=fa[x];fa[x]=r;x=t;}
    return r;
}

int kruskal()
{
    int ans = 0;
    for(int i = 1; i <= V; ++ i) fa[i] = i;
    sort(es+1, es+E+1, cmp);
    for(int i = 1; i <= E; ++ i)
    {
        int fu = find(es[i].from);
        int fv = find(es[i].to);
        if(fu != fv)
        {
            fa[fu] = fv;
            ans += es[i].cost;
        }
    }
    return ans;
}

int main()
{
    cin >> V >> E;
    for(int i = 1; i <= E; ++ i)
    {
        int f, t, d;
        scanf("%d%d%d", &f, &t, &d);
        es[i] = (edge){f,t,d};
    }
    cout << kruskal() << '\n';
    return 0;
}

這裡寫圖片描述

最短路floyd

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define MAXN (110)
int V; 
int dis[MAXN][MAXN];

void floyd()
{
    for(int k = 1; k <= V; ++ k)
        for(int i = 1; i <= V; ++ i)
            for(int j = 1; j <= V; ++ j)
                dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]);
}

int main()
{
    cin >> V;
    memset(dis,63,sizeof(dis));
    for(int i = 1; i <= V; ++ i)
        for(int j = 1; j <= V; ++ j)
            scanf("%d", &dis[i][j]), dis[j][i] = dis[i][j];
    floyd();
    int Q; cin >> Q;
    while(Q--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        printf("%d\n", dis[a][b]);
    }
    return 0;
}

這裡寫圖片描述

最短路spfa

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue> 
using namespace std;

#define MAX_V (2525)
#define MAX_E (6262)
int V, E, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool used[MAX_V];
struct edge{
    int from, to, cost;
}es[MAX_E<<1];

void build(int ff, int tt, int dd)
{
    es[++tot] = (edge){ff,tt,dd};
    nxt[tot] = first[ff];
    first[ff] = tot;
}

#define INF (1e9)
queue <int> q;
void spfa(int s)
{
    fill(dis+1,dis+V+1,INF);
    dis[s] = 0;
    q.push(s);
    used[s] = 1;
    while(q.size())
    {
        int x = q.front();
        q.pop();
        used[x] = 0;
        for(int i = first[x]; i != -1; i = nxt[i])
        {
            int v = es[i].to;
            if(dis[v] > dis[x] + es[i].cost)
            {
                dis[v] = dis[x] + es[i].cost;
                if(!used[v])
                {
                    q.push(v);
                    used[v] = 1;
                }
            }
        }
    }
}

int main()
{
    int Ts, Te;
    cin >> V >> E >> Ts >> Te;
    memset(first,-1,sizeof(first));
    for(int i = 1; i <= E; ++ i)
    {
        int f, t, d;
        scanf("%d%d%d", &f, &t, &d);
        build(f,t,d); build(t,f,d);
    }
    spfa(Ts);
    cout << dis[Te] << '\n';
    return 0;
}

最短路spfa_slf優化

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue> 
using namespace std;

#define MAX_V (2525)
#define MAX_E (6262)
int V, E, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool used[MAX_V];
struct edge{
    int from, to, cost;
}es[MAX_E<<1];

void build(int ff, int tt, int dd)
{
    es[++tot] = (edge){ff,tt,dd};
    nxt[tot] = first[ff];
    first[ff] = tot;
}

#define INF (1e9)
deque <int> q;
void spfa_slf(int s)
{
    fill(dis+1,dis+V+1,INF);
    dis[s] = 0;
    q.push_back(s);
    used[s] = 1;
    while(q.size())
    {
        int x = q.front();
        q.pop_front();
        used[x] = 0;
        for(int i = first[x]; i != -1; i = nxt[i])
        {
            int v = es[i].to;
            if(dis[v] > dis[x] + es[i].cost)
            {
                dis[v] = dis[x] + es[i].cost;
                if(!used[v])
                {
                    if(q.empty()) q.push_back(v);
                    else if(dis[v] <= dis[q.front()]) q.push_front(v);
                    else q.push_back(v);
                    used[v] = 1;
                }
            }
        }
    }
}

int main()
{
    int Ts, Te;
    cin >> V >> E >> Ts >> Te;
    memset(first,-1,sizeof(first));
    for(int i = 1; i <= E; ++ i)
    {
        int f, t, d;
        scanf("%d%d%d", &f, &t, &d);
        build(f,t,d); build(t,f,d);
    }
    spfa_slf(Ts);
    cout << dis[Te] << '\n';
    return 0;
}

最短路spfa判負環

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue> 
using namespace std;

#define MAX_V (2525)
#define MAX_E (6262)
int V, E, EE, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool used[MAX_V];
struct edge{
    int from, to, cost;
}es[MAX_E<<1];

void build(int ff, int tt, int dd)
{
    es[++tot] = (edge){ff,tt,dd};
    nxt[tot] = first[ff];
    first[ff] = tot;
}

#define INF (1e9)
queue <int> q;
int tim[MAX_V];
string spfa(int s)
{
    fill(dis+1,dis+V+1,INF);
    dis[s] = 0;
    q.push(s);
    used[s] = 1;
    while(q.size())
    {
        int x = q.front();
        q.pop();
        used[x] = 0;
        if(++tim[x] > V) return "YES";
        for(int i = first[x]; i != -1; i = nxt[i])
        {
            int v = es[i].to;
            if(dis[v] > dis[x] + es[i].cost)
            {
                dis[v] = dis[x] + es[i].cost;
                if(!used[v])
                {
                    q.push(v);
                    used[v] = 1;
                }
            }
        }
    }
    return "NO";
}

int main()
{
    int T;
    cin >> T;
    while(T --)
    {
        tot = 0;
        memset(first,-1,sizeof(first));
        memset(nxt,0,sizeof(nxt));
        memset(used,0,sizeof(used));
        memset(es,0,sizeof(es));
        memset(tim,0,sizeof(tim));
        while(q.size()) q.pop();

        scanf("%d%d%d", &V, &E, &EE);
        for(int i = 1; i <= E; ++ i)
        {
            int f, t, d;
            scanf("%d%d%d", &f, &t, &d);
            build(f,t,d); build(t,f,d);
        }
        for(int i = 1; i <= EE; ++ i)
        {
            int f, t, d;
            scanf("%d%d%d", &f, &t, &d);
            build(f,t,-d);
        }
        cout << spfa(1) << '\n';
    }
    return 0;
}   

這裡寫圖片描述

最短路 Dijsktra堆優化

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue> 
using namespace std;

#define MAX_V (2525)
#define MAX_E (6262)
int V, E, tot = 0;
int first[MAX_V], nxt[MAX_E<<1], dis[MAX_V];
bool done[MAX_V];
struct edge{
    int from, to, cost;
}es[MAX_E<<1];

void build(int ff, int tt, int dd)
{
    es[++tot] = (edge){ff,tt,dd};
    nxt[tot] = first[ff];
    first[ff] = tot;
}

struct zt{
    int u, d;
};

bool operator < (zt a, zt b)
{
    return a.d > b.d;
}

priority_queue <zt> q;

#define INF (1e9)
void Dijkstra(int s)
{
    fill(dis+1,dis+V+1,INF);
    dis[s] = 0;
    q.push((zt){s,0});
    while(q.size())
    {
        int x = q.top().u;
        q.pop();
        if(done[x]) continue;
        done[x] = 1;
        for(int i = first[x]; i != -1; i = nxt[i])
        {
            int v = es[i].to;
            if(dis[v] > dis[x] + es[i].cost)
            {
                dis[v] = dis[x] + es[i].cost;
                q.push((zt){v,dis[v]});
            }
        }
    }
}
int main()
{
    int Ts, Te;
    cin >> V >> E >> Ts >> Te;
    memset(first,-1,sizeof(first));
    for(int i = 1; i <= E; ++ i)
    {
        int f, t, d;
        scanf("%d%d%d", &f, &t, &d);
        build(f,t,d); build(t,f,d);
    }
    Dijkstra(Ts);
    cout << dis[Te] << '\n';
    return 0;
}

這裡寫圖片描述

次短路_sub_spfa

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <queue>
using namespace std;

#define MAXN (100100)
int V, E, tot = 0;
int first[MAXN], nxt[MAXN<<1], dis1[MAXN], dis2[MAXN];
bool used[MAXN];
struct edge{
    int from, to, cost;
}es[MAXN<<1];

void build(int ff, int tt, int dd)
{
    es[++tot] = (edge){ff,tt,dd};
    nxt[tot] = first[ff];
    first[ff] = tot;
}

#define INF (1e9)
queue <int> q;
void sub_spfa(int s)
{
    fill(dis1+1,dis1+V+1,INF); fill(dis2+1,dis2+V+1,INF);
    dis1[s] = 0;
    q.push(s);
    used[s] = 1;
    while(q.size())
    {
        int x = q.front();
        q.pop();
        used[x] = 0;
        for(int i = first[x]; i != -1; i = nxt[i])
        {
            int v = es[i].to;
            if(dis1[v] > dis1[x] + es[i].cost)
            {
                dis2[v] = dis1[v];
                dis1[v] = dis1[x] + es[i].cost;
                if(!used[v])
                {
                    q.push(v);
                    used[v] = 1;
                }
            }
            else if((dis1[v] < dis1[x]+es[i].cost) && (dis2[v] > dis1[x]+es[i].cost))
            {
                dis2[v] = dis1[x] + es[i].cost;
                if(!used[v])
                {
                    q.push(v);
                    used[v] = 1;
                }
            }
            else if(dis2[v] > dis2[x] + es[i].cost)
            {
                dis2[v] = dis2[x] + es[i].cost;
                if(!used[v])
                {
                    q.push(v);
                    used[v] = 1;
                }
            } 
        }
    }
}

int main()
{
    cin >> V >> E;
    memset(first,-1,sizeof(first));
    for(int i = 1; i <= E; ++ i)
    {
        int f,t,d;
        scanf("%d%d%d", &f, &t, &d);
        build(f,t,d);
    }
    sub_spfa(1);
    if(dis2[V] < INF) cout << dis2[V] << '\n';
    else puts("-1");
    return 0;
}

這裡寫圖片描述

線段樹

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define SZ(x) (tree[x].r-tree[x].l+1)
using namespace std;
typedef long long LL;

#define MAXN (200020)
int xl[MAXN];
struct TREE{
    int l, r, add;
    LL sum;
}tree[MAXN<<2];

void update(int p)
{
    tree[p].sum = tree[L(p)].sum + tree[R(p)].sum;
    return;
}

void build(int l, int r, int p)
{
    tree[p].l = l; tree[p].r = r;
    if(l == r)
    {
        tree[p].sum = xl[l];
        return;
    }
    int mid = (tree[p].l+tree[p].r)>>1;
    build(l,mid,L(p)); build(mid+1,r,R(p));
    update(p);
    return;
}

void spread(int p)
{
    if(tree[p].add)
    {
        tree[L(p)].add += tree[p].add;
        tree[R(p)].add += tree[p].add;
        tree[L(p)].sum += (SZ(L(p))*tree[p].add);
        tree[R(p)].sum += (SZ(R(p))*tree[p].add);
        tree[p].add = 0;
        update(p);
        return;
    }
}

void change(int l, int r, int p, int x)
{
    if(l <= tree[p].l && r >= tree[p].r)
    {
        tree[p].add += x;
        tree[p].sum += (SZ(p)*x);
        return;
    }
    spread(p);
    int mid = (tree[p].l+tree[p].r)>>1;
    if(l <= mid) change(l,r,L(p),x);
    if(r > mid) change(l,r,R(p),x);
    update(p);
    return;
}

LL ask(int l, int r, int p)
{
    if(l <= tree[p].l && r >= tree[p].r)
        return tree[p].sum;
    spread(p);
    LL ans = 0;
    int mid = (tree[p].l+tree[p].r)>>1;
    if(l <= mid) ans += ask(l,r,L(p));
    if(r > mid) ans += ask(l,r,R(p));
    update(p);
    return ans;
}

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++ i) scanf("%d", &xl[i]);
    build(1,n,1);
    int Q;
    cin >> Q;
    while(Q--)
    {
        int t, a, b, x;
        scanf("%d", &t);
        if(t == 1)
        {
            scanf("%d%d%d", &a, &b, &x);
            change(a,b,1,x);
        }
        else{
            scanf("%d%d", &a, &b);
            printf("%lld\n", ask(a,b,1));
        }
    }
    return 0;
}

這裡寫圖片描述

高精度

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;

#define MAXN (100000)
struct Big{
    int a[MAXN];
    int len;
    void print()
    {
        while(!a[this->len] && this->len) --this->len;
        for(int i = this->len; i >= 1; -- i)
            printf("%d", this->a[i]);
        if(!this->len) puts("0");
        else puts("");
    }
};

Big operator + (Big A, Big B)
{
    A.len = max(A.len, B.len)+1;
    for(int i = 1; i <= A.len; ++ i)
    {
        A.a[i] += B.a[i];
        A.a[i+1] += (A.a[i]/10);
        A.a[i] %= 10;
    }
    return A;
}

bool operator < (Big A, Big B)
{
    if(A.len != B.len) return A.len < B.len;
    for(int i = A.len; i >= 1; -- i)
        return A.a[i] < B.a[i];
    return true;
}

Big t;
void swap(Big &A, Big &B) {t = A; A = B; B = t;}

Big operator - (Big A, Big B)
{
    if(A < B) swap(A, B), putchar('-');
    for(int i = 1; i <= A.len; ++ i)
    {
        A.a[i] -= B.a[i];
        if(A.a[i] < 0)
        {
            A.a[i] += 10;
            -- A.a[i+1];
        }
    }
    return A;
}

Big T;
Big operator * (Big A, Big B)
{
    T.len = A.len+B.len;
    for(int i = 1; i <= A.len; ++ i)
        for(int j = 1; j <= B.len; ++ j)
        {
            T.a[i+j-1] += (A.a[i]*B.a[j]);
            T.a[i+j] += (T.a[i+j-1]/10);
            T.a[i+j-1] %= 10;
        }
    return T;
}

char s[MAXN];
void read(Big &A)
{
    scanf("%s", s+1);
    A.len = strlen(s+1);
    for(int i = 1; i <= A.len; ++ i)
        A.a[A.len-i+1] = (int)(s[i]-'0');
}

Big A, B, C;
int main()
{
    read(A); read(B);
    C = A+B;
//  C = A-B;
//  C = A*B;
    C.print();
    return 0;
}

BLESS ALL.

這裡寫圖片描述

(圖侵刪, 圖雜)

這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述這裡寫圖片描述