ACM常用模板

Posted icode-xiaohu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM常用模板相关的知识,希望对你有一定的参考价值。

最大值与次大值的科学求法

   Cm = 0,说明不存在次大值;

    int a[10]={1,2,3,4,45};
    int Zm=0,Cm=0;
    for(int i=0;i<5;i++){
        if(a[i]>Cm){
            Cm=a[i];
        }
        if(Cm>Zm) Zm=Cm;
    }
    cout<<M1<<" "<<M2<<endl;
View Code

数位dp经典模板(不要62)

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
#define pb push_back
#define LL long long
LL dp[20][10];
int a[20];
LL dfs(int pos,int pre,bool lead0,bool limit){
    if(pos==-1) return 1;
    if(!limit && !lead0 && dp[pos][pre]!=-1) return dp[pos][pre];
    int up=limit ?a[pos] :9;
    LL ans=0;
    for(int i=0;i<=up;i++){
        int nle=(i==0&&lead0);
        int nli=(i==up&&limit);
        if(i==4||(i==2&&pre==6)) continue;
        ans+=dfs(pos-1,i,nle,nli);
    }
    if(!limit && !lead0) dp[pos][pre]=ans;
    return ans;
}
LL solve(LL x){
    int w=0;
    while(x){
        a[w++]=x%10;
        x/=10;
    }
    return dfs(w-1,-1,true,true);
}
int main()
{
    memset(dp,-1,sizeof(dp));
    LL l,r;
    while(~scanf("%lld %lld",&l,&r)){
        if(l+r==0) break;
        printf("%lld\\n",solve(r)-solve(l-1));
    }
    return 0;
}
View Code

结构体内部排序的方法(适用于set的自动排序)

struct Node {
    int id,s;
    Node(int _i,int _s):id(_i),s(_s) {}
    bool operator < (const Node& b) const {
        if(s!=b.s) return s<b.s;
        else return id<b.id;
    }
};
View Code

中国剩余定理(互质与非互质通用版)

int m[3],r[3];
int e_gcd(int a,int b,int &x,int &y) {
    if(b==0) {
        x=1;
        y=0;
        return a;
    }
    int ans=e_gcd(b,a%b,x,y);
    int temp=x;
    x=y;
    y=temp-a/b*y;
    return ans;
}
int Zhong() {
    int M = m[0],R = r[0];
    for(int i = 1; i < 3; i++) {
        int c = r[i]-R,x,y;
        int gcd = e_gcd(M,m[i],x,y);
        if(c%gcd != 0) return -1;
        x = c*x;
        x = (x+m[i]) % m[i];
        int X = x*M + R;
        M = m[i]/gcd*M;
        R = X % M;
    }
    return (R%M+M)%M;
}
View Code

线段树(求区间最大值):

const int N = 1e6+5;
#define lc 2*node
#define rc 2*node+1
#define MAX 1e9
int seg[N*4+10],dp[N];
void Build(int node,int l,int r){
    if(l == r) seg[node] = MAX;
    else {
        int mid = (l+r)>>1;
        Build(lc,l,mid);
        Build(rc,mid+1,r);
        seg[node] = min(seg[lc],seg[rc]);
    }
}
void Update(int node,int l,int r,int k,int num){
    if(l==r) {
       seg[node] = num;
       return;
    }
    int mid = (l+r)>>1;
    if(k <= mid) Update(lc,l,mid,k,num);
    else Update(rc,mid+1,r,k,num);
    seg[node] = min(seg[lc],seg[rc]);
}
int query(int node,int l,int r,int ql,int qr){
    int p1,p2;
    if(ql > r || qr < l) return MAX;
    if(l >= ql && r <= qr) return seg[node];
    int mid = (l+r)>>1;
    p1 = query(lc,l,mid,ql,qr);
    p2 = query(rc,mid+1,r,ql,qr);
    return min(p1,p2);
}
View Code

 求逆元(含扩展欧几里得)

ll ex_gcd(ll a,ll b,ll &x,ll &y) {
    if(b==0) {
        x=1;
        y=0;
        return a;
    }
    ll ans=ex_gcd(b,a%b,x,y);
    ll tmp=x;
    x=y;
    y=tmp-a/b*y;
    return ans;
}
View Code

要求 a和b的最大公约数是1,然后x = (x+b)%b 将x转到正确的区间,x就是a的逆元。

zkw费用流

const int N = 2005;
const int M = 56666;
const int INF = 1e9;
const double eps = 1e-4;
struct Edge {
    int next,cap,v;
    double cost;
    Edge() {}
    Edge(int vv,int ca,double co,int ne) {
        v=vv;
        cap = ca;
        cost=co;
        next=ne;
    }
} edge[M];
int head[N],e,vis[N];
double d[N],cost,ans;
int src,des;
void init() {
    memset(head, -1, sizeof(head));
    e = 0;
    ans = cost = 0;
}
void addEdge(int u, int v, int cap, double cost) {
    edge[e] = Edge(v,cap,cost,head[u]);
    head[u] = e++;
    edge[e] = Edge(u,0,-cost,head[v]);
    head[v] = e++;
}
int aug(int u, int f) {
    if(u == des) {
        ans += cost * f;
        return f;
    }
    vis[u] = 1;
    int tmp = f;
    for(int i = head[u]; i != -1; i = edge[i].next)
        if(edge[i].cap && fabs(edge[i].cost)<eps && !vis[edge[i].v]) {
            int delta = aug(edge[i].v, tmp < edge[i].cap ? tmp : edge[i].cap);
            edge[i].cap -= delta;
            edge[i^1].cap += delta;
            tmp -= delta;
            if(!tmp) return f;
        }
    return f - tmp;
}
bool modlabel() {
    for(int i = src; i <= des; i++) d[i] = INF;
    d[des] = 0;
    deque<int>Q;
    Q.push_back(des);
    while(!Q.empty()) {
        int u = Q.front();
        double tmp;
        Q.pop_front();
        for(int i = head[u]; i != -1; i = edge[i].next) {
            tmp =  d[u]-edge[i].cost;
            if(edge[i^1].cap && d[edge[i].v]>tmp+eps){
                d[edge[i].v] = tmp;
                double a = tmp;
                double b = d[Q.empty() ?src :Q.front()];
                (b>a+eps||(fabs(a-b)<eps)) ?Q.push_front(edge[i].v) :Q.push_back(edge[i].v);
            }
        }

    }
    for(int u = src; u <= des; u++)
        for(int i = head[u]; i != -1; i = edge[i].next)
            edge[i].cost += d[edge[i].v] - d[u];
    cost += d[src];
    return d[src] < INF;
}
void costflow() {
    while(modlabel()) {
        do {
            memset(vis, 0, sizeof(vis));
        } while(aug(src, INF));
    }
}
View Code

zkw费用流修正版

const int N = 2005;
const int M = 56666;
const int INF = 1e9;
const double eps = 1e-7;
struct Edge {
    int next,cap,v;
    double cost;
    Edge() {}
    Edge(int vv,int ca,double co,int ne) {
        v=vv;
        cap = ca;
        cost=co;
        next=ne;
    }
} edge[M];
int head[N],e,vis[N];
double d[N],cost,ans;
int src,des;
void init() {
    memset(head, -1, sizeof(head));
    e = 0;
    ans = cost = 0;
}
void addEdge(int u, int v, int cap, double cost) {
    edge[e] = Edge(v,cap,cost,head[u]);
    head[u] = e++;
    edge[e] = Edge(u,0,-cost,head[v]);
    head[v] = e++;
}
int aug(int u, int f) {
    if(u == des) {
        ans += cost * f;
        return f;
    }
    vis[u] = 1;
    int tmp = f;
    for(int i = head[u]; i != -1; i = edge[i].next)
        if(edge[i].cap && fabs(edge[i].cost)<eps && !vis[edge[i].v]) {
            int nxtf = min(tmp,edge[i].cap);
            int delta = aug(edge[i].v,nxtf);
            edge[i].cap -= delta;
            edge[i^1].cap += delta;
            tmp -= delta;
            if(!tmp) return f;
        }
    return f - tmp;
}
bool modlabel() {
    for(int i = src; i <= des; i++) d[i] = INF;
    d[des] = 0;
    deque<int>Q;
    Q.push_back(des);
    while(!Q.empty()) {
        int u = Q.front();
        double a,b;
        Q.pop_front();
        for(int i = head[u]; i != -1; i = edge[i].next) {
            a =  d[u]-edge[i].cost;
            if(edge[i^1].cap && d[edge[i].v]>a+eps) {
                d[edge[i].v] = a;
                b = d[Q.empty() ?src :Q.front()];
                if(b>a+eps||(fabs(a-b)<eps)) {
                    Q.push_front(edge[i].v);
                } else Q.push_back(edge[i].v);
            }
        }
    }
    for(int u = src; u <= des; u++)
        for(int i = head[u]; i != -1; i = edge[i].next)
            edge[i].cost += d[edge[i].v] - d[u];
    cost += d[src];
    return d[src] < INF;
}
void costflow() {
    while(modlabel()) {
        do {
            memset(vis, 0, sizeof(vis));
        } while(aug(src, INF));
    }
}
View Code

 

spfa最小费用最大流

const int N = 105;
const int M = N*N;
const int INF = 1e9;
struct Edge {
    int from, to, cap, flow, cost, next;
};
Edge edge[M];
int head[N],pre[N],dist[N],edgenum;
bool vis[N];
int source, sink;
void init() {
    edgenum = 0;
    memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int w, int c) {
    Edge E1 = {u, v, w, 0, c, head[u]};
    edge[edgenum] = E1;
    head[u] = edgenum++;
    Edge E2 = {v, u, 0, 0, -c, head[v]};
    edge[edgenum] = E2;
    head[v] = edgenum++;
}
bool SPFA(int s, int t) {
    queue<int> Q;
    while(!Q.empty()) Q.pop();
    for(int i=0;i<N;i++) dist[i]=INF;
    memset(vis, false, sizeof(vis));
    memset(pre, -1, sizeof(pre));
    dist[s] = 0;
    vis[s] = true;
    Q.push(s);
    while(!Q.empty()) {
        int u = Q.front();
        Q.pop();
        vis[u] = false;
        for(int i = head[u]; i != -1; i = edge[i].next) {
            Edge E = edge[i];
            if(dist[E.to] > dist[u] + E.cost && E.cap > E.flow) {
                dist[E.to] = dist[u] + E.cost;
                pre[E.to] = i;
                if(!vis[E.to]) {
                    vis[E.to] = true;
                    Q.push(E.to);
                }
            }
        }
    }
    return pre[t] != -1;
}
void MCMF(int s, int t, int &cost, int &flow) {
    flow = 0;
    cost = 0;
    while(SPFA(s, t)) {
        int Min = INF;
        for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) {
            Edge E = edge[i];
            Min = min(Min, E.cap - E.flow);
        }
        for(int i = pre[t]; i != -1; i = pre[edge[i^1].to]) {
            edge[i].flow += Min;
            edge[i^1].flow -= Min;
            cost += edge[i].cost * Min;
        }
        flow += Min;
    }
}
View Code

Dinic算法求最大流(邻接表版本)

#define INF 0x3f3f3f3f
#define MAX_V 20
#define MAX_E 2000
struct edge {
    int to,cap,rev;
    edge(int a=0,int b=0,int c=0) :to(a),cap(b),rev(c) {}
};
vector<edge> G[MAX_V];
int level[MAX_V];
int iter[MAX_V];
void init(int v) {
    for(int i=0; i<=v; i++) G[i].clear();
}
void addedge(int from,int to,int cap) {
    G[from].push_back( edge(to,cap,G[to].size()));
    G[to].push_back( edge(from,0,G[from].size()-1));
}
void bfs(int s) {
    memset(level,-1,sizeof(level));
    queue<int> que;
    level[s]=0;
    que.push(s);
    while(!que.empty()) {
        int v=que.front();
        que.pop();
        for(int i=0; i<G[v].size(); i++) {
            edge &e=G[v][i];
            if(e.cap>0&&level[e.to]<0) {
                level[e.to]=level[v]+1;
                que.push(e.to);
            }
        }
    }
}
int dfs(int v,int t,int f) {
    if(v==t) return f;
    for(int &i=iter[v]; i<G[v].size(); i++) {
        edge &e=G[v][i];
        if(e.cap>0&&level[v]<level[e.to]) {
            int d=dfs(e.to,t,min(f,e.cap));
            if(d>0) {
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}
int max_flow(int s,int t) {
    int flow=0;
    while(true) {
        bfs(s);
        if(level[t]<0) return flow;
        memset(iter,0,sizeof(iter));
        int f;
        while((f=dfs(s,t,INF))>0) flow+=f;
    }
}
View Code

Dinic算法链式前向星版本(可以有序储存反向弧) 

const int INF=0x3f3f3f3f;
const int N=60;
const int M=60*60*2;
int n,p;
int s,t,e_max,fir[N],dis[N],q[N];
struct Node {
    int c;
    int in[15],ou[15];
} a[N];
struct edge {
    int u,v,w,nex;
} e[M];
void add_edge(int u,int v,int w,int x) {
    if(x==2) return;
    e[e_max].u=u;
    e[e_max].v=v;
    e[e_max].w=w;
    e[e_max].nex=fir[u];
    fir[u]=e_max++;
    add_edge(v,u,0,x+1);
}
int bfs() {
    int i,x,v,tail=0,head=0;
    memset(dis,0,sizeof(dis));
    dis[s]=1;
    q[tail++]=s;
    while(head<tail) {
        x=q[head++];
        for(i=fir[x]; i!=-1; i=e[i].nex)
            if(e[i].w&&dis[v=e[i].v]==0) {
                dis[v]=dis[x]+1;
                if(v==t)
                    return 1;
                q[tail++]=v;
            }
    }
    return 0;
}
int dfs(int s,int limit) {
    if(s==t)
        return limit;
    int i,v,tmp,cost=0;
    for(i=fir[s]; i!=-1; i=e[i].nex)
        if(e[i].w&&dis[s]==dis[v=e[i].v]-1) {
            tmp=dfs(v,min(limit-cost,e[i].w));
            if(tmp>0) {
                e[i].w-=tmp;
                e[i^1].w+=tmp;
                cost+=tmp;
                if(limit==cost)
                    break;
            } else dis[v]=-1;
        }
    return cost;
}
int Dinic() {
    int ans=0;
    while(bfs())
        ans+=dfs(s,INF);
    return ans;
}
void init() {
    s=0;
    t=n+1;
    memset(fir,-1,sizeof(fir));
    e_max=0;
}
View Code

Dinic算法(修正版)

const int N = 105;
const int INF = 1e9;
const int M = N*N;
struct edge {
    int u,v,w,nex;
} e[M];
int s,t,e_max,fir[N],dis[N],q[N];
void init() {
    memset(fir,-1,sizeof(fir));
    e_max=0;
}
void add_edge(int u,int v,int w,int x) {
    if(x==2) return;
    e[e_max].u=u;
    e[e_max].v=v;
    e[e_max].w=w;
    e[e_max].nex=fir[u];
    fir[u]=e_max++;
    add_edge(v,u,0,x+1);
}
int bfs() {
    int i,x,v,tail=0,head=0;
    memset(dis,0,sizeof(dis));
    dis[s]=1;
    q[tail++]=s;
    while(head<tail) {
        x=q[head++];
        for(i=fir[x]; i!=-1; i=e[i].nex)
            if(e[i].w&&dis[v=e[i].v]==以上是关于ACM常用模板的主要内容,如果未能解决你的问题,请参考以下文章

ACM竞赛常用头文件模板

ACM常用模板

acm学习总结

如何选择和使用ACM LaTeX模板

如何选择和使用ACM LaTeX模板

[AndroidStudio]_[初级]_[配置自动完成的代码片段]