一些常用算法的代码(1)

为了简洁,部分算法我只贴函数或过程

KMP

int kmp(string s1,string s)
{
    int i,j=0;
    long long ans=0;
    next[1]=0;
    fo(i,2,m)
    {
        while (j>0&&t[j]!=t[i-1]) j=next[j];
        if (t[j]==t[i-1]) j++;
        next[i]=j;
    }
    fo(i,1,s.length())
    {
        while (j>0&&s1[j]!=s[i-1]) j=next[j];
        if (s1[j]==s[i-1]) j++;
        if (j==m) 
        {
            ans++;
            j=next[j];
        }
    }
    return ans;
}

高精度加,乘,减,比大小,对单精度取模

arr pl(arr a,arr b)
{
    int la,lb,lc,i;
    arr c;
    la=a.a[0];
    lb=b.a[0];
    memset(c.a,0,sizeof(c.a));
    fo(i,1,max(la,lb))
    {

        c.a[i]=c.a[i]+a.a[i]+b.a[i];
        c.a[i+1]=c.a[i+1]+c.a[i]/10;
        c.a[i]=c.a[i]%10;
    }
    lc=max(la,lb);
    if (c.a[lc+1]!=0) lc++;
    while(c.a[lc]==0&&lc>1) lc--;
    c.a[0]=lc;
    return c;
}
arr ms(arr a,arr b)
{

    int la,lb,lc,i,j;
    arr c;
    la=a.a[0];
    lb=b.a[0];
    memset(c.a,0,sizeof(c.a));
    fo(i,1,max(la,lb))
    {
        if (a.a[i]-b.a[i]<0)
        {
            a.a[i]+=10;
            a.a[i+1]--;
        }
        c.a[i]=a.a[i]-b.a[i];
    }
    lc=la;
    while(c.a[lc]==0&&lc>1) lc--;
    c.a[0]=lc;
    return c;
}
arr ti(arr a,arr b)
{
    int la,lb,lc,i,j;
    arr c;
    la=a.a[0];
    lb=b.a[0];
    memset(c.a,0,sizeof(c.a));
    fo(i,1,lb)
    {
        fo(j,1,la)
        {
            c.a[i+j-1]=c.a[i+j-1]+b.a[i]*a.a[j];
            c.a[i+j]=c.a[i+j]+c.a[i+j-1]/10;
            c.a[i+j-1]=c.a[i+j-1]%10;
        }
    }
    lc=la+lb-1;
    if (c.a[lc+1]!=0) lc++;
    while(c.a[lc]==0&&lc>1) lc--;
    c.a[0]=lc;
    return c;
}
bool larger(arr a,arr b)
{
    if (a.a[0]>b.a[0]) return 1;
    if (a.a[0]<b.a[0]) return 0;
    {
        int i;
        fod(i,a.a[0],1)
        {
            if (a.a[i]>b.a[i]) return 1;
            if (a.a[i]<b.a[i]) return 0;
        }
        return 0;
    }
}
int mod(arr a,int b)
{
    int i;
    long long s=0;
    fod(i,a.a[0],1)
    {
        s=(s*10+a.a[i])%b;
    }
    int s1=s;
    return s1;
}

匈牙利算法

bool find(int k)
{
    int i,j;
    fo(i,1,a[k][0])
    {
        int p=a[k][i];
        if (bz[p]==0)
        {
            bz[p]=1;
            if (dt[p]==0||find(dt[p])) 
            {
                dt[p]=k;
                return 1;
            }
        }
    }
    return 0;
}

最大流SAP-GAP算法

int GAP(int p,int s)
{
    int i,j,q,mh,l;
    if (p==m) return(s);
    mh=m+1;
    fo(i,1,a[p][0])
    {
        q=a[p][st[p]];
        if (a1[p][q]>0)
        {
            if (h[p]==h[q]+1)
            {
                l=GAP(q,min(s,a1[p][q]));
                if (l>0)
                {
                    a1[p][q]-=l;
                    a1[q][p]+=l;
                    return(l);
                }
                if (h[1]>m) return(0);
            }
            mh=min(mh,h[p]+1);
        }
        st[p]++;
        if (st[p]>a[p][0]) st[p]=1;
    }
    vh[h[p]]--;
    if(vh[h[p]]==0) h[1]=m+1;
    h[p]=mh;
    vh[h[p]]++;
    return(0);
}

树状数组各种操作

int lowbit(int x)
{
    return (x&-x);
}
int getsum(int k)
{
    long long s=0;
    while (k>0)
    {
        s+=c[k];
        k-=lowbit(k);
    }
    return s;
}
void change(int k,long long v)
{
    while (k<=n)
    {
        c[k]+=v;
        k+=lowbit(k);
    }
}

矩阵乘法快速幂

struct note
{
    long long a[n][n];
};
note ti(note a,note b)
{
    note c;
    int i,j,k;
    fo(i,0,n-1)
        fo(j,0,n-1)
        {
            c.a[i][j]=0;
            fo(k,0,3)
                c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%p);
        }
    return c;
}
note ksm(note k,long long n)
{
    if (n==1) return k;
    note s=ksm(k,n/2);
    if (n%2==0) return ti(s,s);
    else return ti(ti(s,s),k);
}

SPFA

void spfa(int l)
{
    int i,j,now,dt[MAXL],bz[n];
    memset(bz,0,sizeof(bz));
    i=0;
    j=1;
    dt[1]=l;
    bz[l]=1;
    dis[l]=0;
    while (i<j)
    {
        i++;
        int k;
        now=dt[i];
        fo(k,1,a[now][0][0])
        {
            int p=a[now][k][0];
            if (dis[p]>dis[now]+a[now][k][1])
            {
                dis[p]=dis[now]+a[now][k][1];
                if (bz[p]==0) 
                {
                    dt[++j]=p;
                    bz[p]=1;
                }
            }
        }
        bz[now]=0;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值