代码模板(持续更新)

字符串:

  KMP算法:

 

int Next[maxn];

void Get_Next(char *S,int len)
{
    int i=0,j=-1;
    Next[0]=-1;
    while(i<len)
    {
        if(j==-1||S[i]==S[j])
        {
            i++;j++;Next[i]=j;
        }
        else j=Next[j];
    }
}

void KMP(char *S,char *T,int lens,int lent)
{
    Get_Next(T,lent);
    int i=0,j=0;
    while(i<lens)
    {
        if(j==-1||S[i]==T[j])
        {
            i++;j++;
        }
        else j=Next[j];
        if(j==lent)
        {
            printf("%d\n",i-lent+1);
        }
    }
}

 

 

 

  EX_KMP:

 

int Next[maxn],ext[maxn];

void Get_Next(char *S,int len)
{
    int k=0;Next[0]=len;
    while(k+1<len&&S[k]==S[k+1]) k++;
    Next[1]=k;k=1;
    for(int i=2;i<len;i++)
    {
        if(Next[i-k]+i<Next[k]+k) Next[i]=Next[i-k];
        else
        {
            int j=max(0,Next[k]+k-i);
            while(i+j<len&&S[i+j]==S[j]) j++;
            Next[i]=j;k=i;
        }
    }
}

void EXKMP(char *S,char *T,int *extend,int lens,int lent)
{
    Get_Next(T,lent);
    int k=0;
    while(k<lens&&k<lent&&S[k]==T[k]) k++;
    extend[0]=k;k=0;
    for(int i=1;i<lens;i++)
    {
        if(Next[i-k]+i<extend[k]+k) extend[i]=Next[i-k];
        else
        {
            int j=max(0,extend[k]+k-i);
            while(i+j<lens&&j<lent&&S[i+j]==T[j]) j++;
            extend[i]=j;k=i;
        }
    }
}

 

 

 

图论:

  匈牙利算法:

 

vector<int> G[maxn];
int vis[maxn],l[maxn];

bool dfs(int u)
{
    int len=G[u].size();
    for(int i=0;i<len;i++)
    {
        int v=G[u][i];
        if(!vis[v])
        {
            vis[v]=1;
            if(l[v]==-1||dfs(l[v]))
            {
                l[v]=u;return true;
            }
        }
    }
    return false;
}

int hungary(int n)
{
    memset(l,-1,sizeof(l));
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        if(dfs(i)) cnt++;
    }
    return cnt;
}

 

 

 

   网络流:

 

//点从1开始编号
struct Edge
{
    int to,flow,nxt;
} edges[maxn*maxn];

int cnt,n,m;
int head[maxn],dep[maxn],a[maxn][maxn];

void AddEdge(int from,int to,int flow)
{
    cnt++;edges[cnt].to=to;edges[cnt].flow=flow;
    edges[cnt].nxt=head[from];head[from]=cnt;
    cnt++;edges[cnt].to=from;edges[cnt].flow=0;
    edges[cnt].nxt=head[to];head[to]=cnt;
}

int BFS(int s,int t)
{
    queue<int> q;
    dep[s]=1;q.push(s);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int x=head[u];x!=0;x=edges[x].nxt)
        {
            if(dep[edges[x].to]==0&&edges[x].flow>0)
            {
                dep[edges[x].to]=dep[u]+1;
                q.push(edges[x].to);
            }
        }
    }
    return (dep[t]==0)?0:1;
}

int DFS(int now,int RouteMinFlow,int t)
{
    int OldRouteMinFlow=0;
    if(RouteMinFlow<=0||now==t) return RouteMinFlow;
    for(int x=head[now];x!=0;x=edges[x].nxt)
    {
        if(dep[edges[x].to]==dep[now]+1)
        {
            int temp=DFS(edges[x].to,min(RouteMinFlow,edges[x].flow),t);
            edges[x+1].flow+=temp;edges[x].flow-=temp;
            RouteMinFlow-=temp;OldRouteMinFlow+=temp;
            if(RouteMinFlow==0) break;
        }
    }
    return OldRouteMinFlow;
}

int maxflow(int s,int t)
{
    int ans=0;
    while(BFS(s,t))
    {
        ans+=DFS(1,inf,t);
        memset(dep,0,sizeof(dep));
    }
    return ans;
}

void init()
{
    cnt=0;memset(dep,0,sizeof(dep));
    memset(head,0,sizeof(head));
}

 

   最小费用最大流:

 

struct Edge
{
    int to,cap,cost,nxt;
} edges[maxn*maxn];

int cnt;
int d[maxn],head[maxn],pre[maxn],path[maxn];

void AddEdge(int from,int to,int cap,int cost)
{
    edges[cnt].to=to;edges[cnt].cap=cap;edges[cnt].cost=cost;
    edges[cnt].nxt=head[from];head[from]=cnt++;
    edges[cnt].to=from;edges[cnt].cap=0; edges[cnt].cost=-cost;
    edges[cnt].nxt=head[to];head[to]=cnt++;
}

bool Spfa(int s,int t)
{
    memset(pre,-1,sizeof(pre));
    memset(d,0x3f,sizeof(d));
    queue<int> q;
    q.push(s);d[s]=0;
    while (!q.empty())
    {
        int u=q.front();q.pop();
        for(int e=head[u];e!=-1;e=edges[e].nxt)
        {
            int v=edges[e].to;
            if(edges[e].cap>0&&d[u]+edges[e].cost<d[v])
            {
                d[v]=d[u]+edges[e].cost;
                pre[v]=u;path[v]=e;
                q.push(v);
            }
        }
    }
    return (pre[t]==-1)?false:true;
}

int MinCostFlow(int s,int t)
{
    int cost=0,flow=0;
    while(Spfa(s,t))
    {
        int f=inf;
        for(int u=t;u!=s;u=pre[u])
        {
            if(edges[path[u]].cap<f)
                f=edges[path[u]].cap;
        }
        flow+=f;
        cost+=d[t]*f;
        for(int u=t;u!=s;u=pre[u])
        {
            edges[path[u]].cap-=f;
            edges[path[u]^1].cap+=f;
        }
    }
    return cost;
}

int main()
{
    cnt=0;memset(head,-1,sizeof(head));
    return 0;
}

  

  强连通分量(tarjan):

vector<int> G[maxn];
stack<int> S;

int pre[maxn],low[maxn],scc[maxn],scc_val[maxn]; int scc_cnt,dfs_clock; int n,m;void dfs(int u) { pre[u]=low[u]=++dfs_clock; int len=G[u].size();S.push(u); for(int i=0;i<len;i++) { int v=G[u][i]; if(!pre[v]) { dfs(v); low[u]=min(low[u],low[v]); } else if(!scc[v]) low[u]=min(low[u],pre[v]); } if(pre[u]==low[u]) { scc_cnt++;int cnt=0; for(;;) { int t=S.top();S.pop(); scc[t]=scc_cnt;cnt++; if(t==u) break; } scc_val[scc_cnt]=cnt; } } void find_scc() { memset(pre,0,sizeof(pre)); memset(low,0,sizeof(low)); memset(scc,0,sizeof(scc)); scc_cnt=0;dfs_clock=0; for(int i=1;i<=n;i++) { if(!pre[i]) dfs(i); } }

 

  Dijkstra:

 

void dijkstra(int u,int n)
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) dist[i]=G[u][i];
    vis[u]=1;
    for(int i=1;i<n;i++)
    {
        int mind=inf,v=u;
        for(int j=1;j<=n;j++)
        {
            if((!vis[j])&&dist[j]<mind)
            {
                mind=dist[j];v=j;
            }
        }
        vis[v]=1;
        for(int j=1;j<=n;j++)
        {
            if(vis[j]) continue;
            if(dist[j]>mind+G[v][j])
            {
                dist[j]=mind+G[v][j];
            }
        }
    }
}

 

   最大团: 

int G[maxn][maxn],n;
int num[maxn];
int V[maxn][maxn],ans=0;

bool dfs(int tot,int cnt)
{
    if(tot==0)
    {
        if(cnt>ans) {ans=cnt;return true;}
    }
    for(int i=0;i<tot;i++)
    {
        if(cnt+(tot-i)<=ans) return false;
        if(cnt+num[V[cnt][i]]<=ans) return false;
        int k=0;
        for(int j=i+1;j<tot;j++)
            if(G[V[cnt][i]][V[cnt][j]])
                V[cnt+1][k++]=V[cnt][j];
        if(dfs(k,cnt+1)) return true;
    }
    return false;
}

void query_max()
{
    ans=1;
    for(int i=n;i>0;i--)
    {
        int k=0;
        for(int j=i+1;j<=n;j++)
        {
            if(G[i][j]) V[1][k++]=j;
        }
        dfs(k,1);
        num[i]=ans;
    }
}

 

数论:

  中国剩余定理:

 

ll a[maxn],m[maxn];

ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}

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 temp=x;x=y;y=temp-(a/b)*y;
    return ans;
}

ll Inv(ll a,ll b)
{
    ll x,y,d;
    d=ex_gcd(a,b,x,y);
    return (d!=1)?-1:(x%b+b)%b;
}

bool Merge(ll a1,ll m1,ll a2,ll m2,ll &a3,ll &m3)
{
    ll d=gcd(m1,m2),c=a2-a1;
    if(c%d) return false;
    c=(c%m2+m2)%m2;
    m1/=d;m2/=d;c/=d;
    c*=Inv(m1,m2);
    c%=m2;c*=m1*d;c+=a1;
    m3=m1*m2*d;
    a3=(c%m3+m3)%m3;
    return true;
}

ll CRT(int n)
{
    ll a1=a[1],m1=m[1];
    for(int i=2;i<=n;i++)
    {
        ll a2=a[i],m2=m[i],m3, a3;
        if(!Merge(a1,m1,a2,m2,a3,m3)) return -1;
        a1=a3;m1=m3;
    }
    return (a1%m1+m1)%m1;
}

/*ll CRT(int n)                //m两两互素时
{
    ll M=1,ans=0;
    for(int i=1;i<=n;i++) M*=m[i];
    for(int i=1;i<=n;i++)
    {
        ll x,y,Mi=M/m[i];
        ex_gcd(Mi,m[i],x,y);
        ans=(ans+Mi*x*a[i])%M;
    }

    return (ans<0)?ans+M:ans;
}*/

 

稳定婚姻问题:

 

int a[maxn][maxn],b[maxn][maxn],n; //a-->男生的期望   b-->女生的期望     //第二维从0开始
int ans[maxn];   //每位男生选中的女生
int manStartPos[maxn];//记录每位男生选取的是心目中第几位的女生
int ladyNow[maxn];//女生对应的男生

int GetPositionFromLady(int laday, int man)
{
    for(int i=0;i<n;i++)
        if(b[laday][i]==man)
            return i;
    return -1;
}

void ChoosePartener(stack<int>& S, int manPos)
{
    //选择自己名单上排在首位的女人
    int perferLady = a[manPos][manStartPos[manPos]];
    //如果该女孩没有接受过表白,则接受该男孩的表白
    if(ladyNow[perferLady]==-1)
    {
        ladyNow[perferLady]=manPos;
        ans[manPos]=perferLady;
    }
    //如果已经有人向她表白,则判断其现在拥有的有没有现在追求的好
    else
    {
        int oldPos=GetPositionFromLady(perferLady,ladyNow[perferLady]);
        int newPos=GetPositionFromLady(perferLady,manPos);
        if(oldPos<newPos)
        {
            manStartPos[manPos]++;//说明该女生更喜欢现在拥有的,选心目中第二位
            //加入单身行列
            S.push(manPos);
        }
        else //换男友
        {
            //被甩的男友恢复自由身份
            manStartPos[ladyNow[perferLady]]++;
            //加入单身行列
            S.push(ladyNow[perferLady]);
            //将追求的男士改为现任男友
            ladyNow[perferLady]=manPos;
            ans[manPos]=perferLady;
        }
    }
}

void solve()
{
    memset(ladyNow,-1,sizeof(ladyNow));
    memset(manStartPos,0,sizeof(manStartPos));
    memset(ans,0,sizeof(ans));

    stack<int> S; // 还处于单身的男士

    //进行第一轮迭代,每个男生都选择自己名单上排在首位的女生。
    for(int i=1;i<=n;i++) ChoosePartener(S,i);

    while(S.size()!=0)
    {
        int manPos=S.top();S.pop();
        ChoosePartener(S,manPos);
    }
}

 

 

高斯消元:

int var,equ;
double a[250][250],x[250];

int Gauss()
{
    for(int k=0,col=0;k<equ&&col<var;k++,col++)
    {
        int max_r=k;
        for(int i=k+1;i<equ;i++)
            if(fabs(a[i][col])>fabs(a[max_r][col])) max_r=i;
        if(fabs(a[max_r][col])<Eps) return 0;
        if(k!=max_r)
        {
            for(int j=col;j<var;j++)
                swap(a[k][j],a[max_r][j]);
            swap(x[k],x[max_r]);
        }
        x[k]/=a[k][col];
        for(int j=col+1;j<var;j++) a[k][j]/=a[k][col];
        a[k][col]=1;
        for(int i=0;i<equ;i++)
            if(i!=k)
            {
                x[i]-=x[k]*a[i][col];
                for(int j=col+1;j<var;j++) a[i][j]-=a[k][j]*a[i][col];
                a[i][col]=0;
            }
    }
    return 1;
}

 

数位DP:

int a[20];
ll dp[20][state];//不同题目状态不同

ll dfs(int pos,/*state变量*/,bool lead/*前导零*/,bool limit/*数位上界变量*/)//不是每个题都要判断前导零  
{ 
    if(pos==-1) return 1;
    if(!limit&&!lead&&dp[pos][state]!=-1) return dp[pos][state];
    int up=limit?a[pos]:9;
    ll ans=0;
    for(int i=0;i<=up;i++)
    {
        if() ...  
        else if()...  
        ans+=dfs(pos-1,/*状态转移*/,lead && i==0,limit && i==a[pos])
        /*这里还算比较灵活,不过做几个题就觉得这里也是套路了 
        大概就是说,我当前数位枚举的数是i,然后根据题目的约束条件分类讨论 
        去计算不同情况下的个数,还有要根据state变量来保证i的合法性,比如题目 
        要求数位上不能有62连续出现,那么就是state就是要保存前一位pre,然后分类, 
        前一位如果是6那么这意味就不能是2,这里一定要保存枚举的这个数是合法*/
    }  
    if(!limit&&!lead) dp[pos][state]=ans;
    return ans;
}
ll solve(ll x) {
int pos=0; while(x)//把数位都分解出来 { a[pos++]=x%10;//个人老是喜欢编号为[0,pos),看不惯的就按自己习惯来,反正注意数位边界就行 x/=10; } return dfs(pos-1,/*一系列状态 */,true,true); }

 

多项式类:

struct polynomial
{
    int num[1200],len;
    polynomial() {mes(num,0);len=0;}
    polynomial(int *_num,int _len) {FOR(i,0,_len) num[i]=_num[i];_len=len;}

    ///先输入最高次项的指数,再依次(从低到高)输入每项的系数
    void input() {scanfi(len);FOR(i,0,len) scanfi(num[i]);}

    void print(char v)
    {
        if(len<0) {printf("Error!!!!\n");return;}
        bool flag=false;
        for(int i=len;i>=1;i--)
        {
            if(num[i]==0) continue;
            if(num[i]>0) {if(flag) printf("+");}else if(num[i]==-1) printf("-");
            abs(num[i])==1?true:printf("%d",num[i]);flag=true;
            printf("%c",v);if(i!=1) printf("^%d",i);
        }
        if(num[0]>0&&flag) printf("+");
        if(num[0]!=0) printf("%d",num[0]);else if(!flag) printf("0");
    }

    void print_endl(char v) {print(v);print_b;}

    polynomial operator + (polynomial a)
    {
        polynomial c;c.len=max(len,a.len);
        FOR(i,0,c.len) c.num[i]=num[i]+a.num[i];
        while(c.len>0&&c.num[c.len]==0) c.len--;return c;
    }

    polynomial operator - (polynomial a)
    {
        polynomial c;c.len=max(len,a.len);
        FOR(i,0,c.len) c.num[i]=num[i]-a.num[i];
        while(c.len>0&&c.num[c.len]==0) c.len--;return c;
    }

    polynomial operator * (int a)
    {
        polynomial c;c.len=len;
        FOR(i,0,len) c.num[i]=num[i]*a;
        while(c.len>0&&c.num[c.len]==0) c.len--;return c;
    }

    polynomial operator * (polynomial a)
    {
        polynomial c;c.len=len+a.len;
        FOR(i,0,len) FOR(j,0,a.len) c.num[i+j]+=num[i]*a.num[j];
        while(c.len>0&&c.num[len]==0) c.len--;return c;
    }

    polynomial operator / (polynomial a)
    {
        polynomial c;c.len=len-a.len;
        if(c.len<0) return c;
        polynomial d=*this;
        for(int i=len;i>=a.len;i--)
        {
            if(d.num[i]%a.num[a.len]!=0) {c.len=-1;return c;}
            int t=d.num[i]/a.num[a.len];
            if(t!=0)
            {
                FOR(j,0,a.len) d.num[i-j]-=a.num[a.len-j]*t;
                c.num[i-a.len]+=t;
            }
        }
        while(d.len>0&&d.num[len]==0) d.len--;
        if(d.len!=0) {c.len=-1;return c;}
        return c;
    }

    polynomial operator % (polynomial a)
    {
        polynomial c;c.len=len-a.len;
        if(c.len<0) return c;
        polynomial d=*this;
        for(int i=len;i>=a.len;i--)
        {
            if(d.num[i]%a.num[a.len]!=0) {c.len=-1;return c;}
            int t=d.num[i]/a.num[a.len];
            if(t!=0)
            {
                FOR(j,0,a.len) d.num[i-j]-=a.num[a.len-j]*t;
                c.num[i-a.len]+=t;
            }
        }
        return d;
    }

    bool operator < (polynomial a)
    {
        if(len!=a.len) return len<a.len;
        for(int i=len;i>=0;i--)
            if(num[i]!=a.num[i])
            {
                if(abs(num[i])!=abs(a.num[i])) return abs(num[i])<abs(a.num[i]);
                else return num[i]<0;
            }
        return false;
    }

    bool operator > (polynomial a) {return a<*this;}
    bool operator <= (polynomial a) {return !(*this>a);}
    bool operator >= (polynomial a) {return !(*this<a);}
    bool operator != (polynomial a) {return a<*this||*this<a;}
    bool operator == (polynomial a) {return !(a<*this)&&!(*this<a);}

    polynomial operator += (polynomial a) {return *this=*this+a;}
    polynomial operator -= (polynomial a) {return *this=*this-a;}
    polynomial operator *= (polynomial a) {return *this=*this*a;}
    polynomial operator /= (polynomial a) {return *this=*this/a;}
    polynomial operator %= (polynomial a) {return *this=*this%a;}
};

 

posted @ 2017-03-17 10:31  CtrlKismet  阅读(237)  评论(0编辑  收藏  举报