模板

 

并查集:

模板1

int find(int x)
{
    if(x!=f[x])
        f[x]=find(f[x]);
    return f[x];
}

 

模板2

int find(int x)
{
    int tem=x,pan;
    while(x!=f[x])
    {
        x=f[x];
    }
    while(tem!=f[tem])
    {
        pan=tem;
        tem=f[pan];
        f[pan]=x;
    }
    return x;
}

逆元模板:

#include<stdio.h>
long long ex_gcd(long long a,long long b,long long &x,long long &y)//扩展欧几里得(扩展gcd)
{
    if (a==0&&b==0) return -1;
    if (b==0)
    {
        x=1;
        y=0;
        return a;
    }
    long long d=ex_gcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

long long mod_inverse(long long a,long long n)//乘法逆元
{
    long long x,y;
    long long d = ex_gcd(a,n,x,y);
    return (x%n+n)%n;
}

KMP:

void kmp()
{
    int j=0;
    for(int i=1;i<=m;)
    {
        if(j==0||T[i]==T[j])
        {
            nextt[++i]=++j;
        }
        else
            j=nextt[j];
    }
}

 

最大最小表示法模板:

char a[1000010];
int posmin(int len)//最小表示法
{
    int i=0,j=1,k=0;
    while(i<len&&j<len&&k<len)
    {
        int pan=a[(i+k)%len]-a[(j+k)%len];
        if(pan==0)
            k++;
        else
        {
            if(pan>0)
                i+=k+1;
            else
                j+=k+1;
            if(i==j)
                j++;
            k=0;
        }
    }
    return min(i+1,j+1);
}
int posmax(int len)//最大表示法
{
    int i=0,j=1,k=0;
    while(i<len&&j<len&&k<len)
    {
        int pan=a[(i+k)%len]-a[(j+k)%len];
        if(pan==0)
            k++;
        else
        {
            if(pan>0)
                j+=k+1;
            else
                i+=k+1;
            if(i==j)
                j++;
            k=0;
        }
    }
    return min(i+1,j+1);
}

Manacher:

 

#include<algorithm>
#include<string.h>
#include<stdio.h>
#define M 110010
#define inf 0x3f3f3f
using namespace std;
char a[M],b[2*M];
int iny[M*2];
void init_manacher()
{
    int len=strlen(a);
    int l=0;
    b[l++]='^';
    b[l++]='#';
    for(int i=0; i<len; i++)
    {
        b[l++]=a[i];
        b[l++]='#';
    }
    b[l++]='!';
}
int manacher()
{
    int len=strlen(a);
    memset(iny,0,sizeof(iny));
    int mi=0,di=0,ans=0;
    for(int i=0; i<=len*2; i++)
    {
        if(mi>i)
            iny[i]=min(mi-i,iny[2*di-i]);
        else
            iny[i]=1;
        while(b[iny[i]+i]==b[i-iny[i]])iny[i]++;
        if(iny[i]+i>mi)
        {
            mi=iny[i]+i;
            di=i;
        }
        ans=max(ans,iny[i]-1);
    }
    return ans;
}
int main()
{
    while(~scanf("%s",a))
    {
        init_manacher();
        printf("%d\n",manacher());
    }
}

指针字典树:HDU - 1251

 
#include<stdio.h>
#include<algorithm>
#include<string.h>'
#define inf 0x3f3f3f
using namespace std;
struct Trie
{
    int v;
    Trie *next[26];
};
Trie root;
char a[15];
void create_Tire(char *str)
{
    Trie *p=&root,*q;
    int len=strlen(str);
    for(int i=0;i<len;i++)
    {
        int di=str[i]-'a';
        if(p->next[di]==NULL)
        {
            q=(Trie *)malloc(sizeof(Trie));
            q->v=1;
            for(int i=0;i<26;i++)
                q->next[i]=NULL;
            p->next[di]=q;
            p=q;
        }
        else
        {
            p=p->next[di];
            p->v++;
        }
    }
}
int find_Tire(char *str)
{
    int len=strlen(a);
    Trie *p=&root,*q;
    for(int i=0;i<len;i++)
    {
        int di=str[i]-'a';
        if(p->next[di]==NULL)
            return 0;
        p=p->next[di];

    }
    return p->v;
}
int main()
{
    while(gets(a),a[0]!='\0')
    {
        create_Tire(a);
    }
    while(~scanf("%s",a))
    {
        printf("%d\n",find_Tire(a));
    }
}

 

指针字典树释放:

void clear_Trie(Trie *p)
{
    for(int i=0; i<26; i++)
    {
        if(p->next[i]!=NULL)
        {
            clear_Trie(p->next[i]);
            p->next[i]=NULL;
        }
    }
    if(p!=&root)
        free(p);
}

数组模拟字典树:   HDU - 1251

#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
int trie[1000000][26];
int book[1000000];
char a[15];
int tot;
void create_Trie(char *str)
{
    int root=0;
    while(*str)
    {
        int di=*str-'a';
        if(trie[root][di]==0)
            trie[root][di]=++tot;
        root=trie[root][di];
        book[root]++;
        str++;
    }
}
int find_Trie(char *str)
{
    int root=0;
    while(*str)
    {
        int di=*str-'a';
        if(trie[root][di]==0)
        {
            return 0;
        }
        root=trie[root][di];
        str++;
    }
    return book[root];
}
int main()
{
    tot=0;
    while(gets(a),a[0]!='\0')
    {
        create_Trie(a);
    }
    while(~scanf("%s",a))
    {
        printf("%d\n",find_Trie(a));
    }
}

AC自动机指针模板:    HDU 2222

#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
char a[70],s[1000010];
struct node
{
    int v;
    node *next[26];
    node *fail;
};
node root;
node *que[1000010];
int cut;
void init(node *q)
{
    for(int i=0; i<26; i++)
    {
        q->next[i]=NULL;
    }
    q->v=0;
    q->fail=NULL;
}
void Trie_creat(char *str)
{
    node *p=&root,*q;
    while(*str)
    {
        int di=*str-'a';
        if(p->next[di]==NULL)
        {
            q=(node *)malloc(sizeof(node));
            init(q);
            p->next[di]=q;
        }
        p=p->next[di];
        str++;
    }
    p->v++;
}
void init_AC_automatiom()
{
    int head=0,tail=0;
    que[tail++]=&root;
    node *temp,*p;
    while(head<tail)
    {
        temp=que[head++];
        for(int i=0;i<26;i++)
        {
            if(temp->next[i])
            {
                if(temp==&root)
                {
                    temp->next[i]->fail=&root;
                }
                else
                {
                    p=temp->fail;
                    while(p)
                    {
                        if(p->next[i])
                        {
                            temp->next[i]->fail=p->next[i];
                            break;
                        }
                        p=p->fail;
                    }
                    if(p==NULL)temp->next[i]->fail=&root;
                }
                que[tail++]=temp->next[i];
            }
        }
    }
}
int AC_automation(char *str)
{
    node *p=&root,*temp;
    while(*str)
    {
        int di=*str-'a';
        while(p->next[di]==NULL&&p!=&root)p=p->fail;
        p=p->next[di];
        if(!p)p=&root;
        temp=p;
        while(temp!=&root)
        {
            if(temp->v>=0)
            {
                cut+=temp->v;
                temp->v=-1;
            }
            else break;
            temp=temp->fail;
        }
        str++;
    }
}
int main()
{
    int n,t;
    scanf("%d",&t);
    while(t--)
    {
        init(&root);
        cut=0;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%s",a);
            Trie_creat(a);
        }
        init_AC_automatiom();
        scanf("%s",s);
        AC_automation(s);
        printf("%d\n",cut);
    }
}

AC自动机数组模拟模板   HDU 2896

#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<queue>
#define M 100010
using namespace std;
int Trie[M][130],v[M],tot,n,m,fail[M],vis[M],ans[510],bp;
char a[10010];
queue<int>q;
void Trie_creat(char *str,int x)
{
    int p=0;
    while(*str)
    {
        int di=*str;
        if(!Trie[p][di])
        {
            Trie[p][di]=++tot;
        }
        p=Trie[p][di];
        str++;
    }
    v[p]=x;
}
void init_fail()
{
    q.push(0);
    int p;
    while(!q.empty())
    {
        p=q.front();
        q.pop();
        for(int i=0;i<130;i++)
        {
            if(Trie[p][i])
            {
                int tem=fail[p];
                while(tem>=0)
                {
                    if(Trie[tem][i])
                    {
                        fail[Trie[p][i]]=Trie[tem][i];
                        break;
                    }
                    tem=fail[tem];
                }
                q.push(Trie[p][i]);
            }
        }
    }
}
int AC_automation(char *str)
{
    int p=0;
    while(*str)
    {
        int di=*str;
        while(!Trie[p][di]&&p!=0)p=fail[p];
        p=Trie[p][di];
        int temp=p;
        while(temp&&vis[temp]>=0)
        {
            if(v[temp])
            {
                ans[bp++]=v[temp];
            }
            vis[temp]=-1;
            temp=fail[temp];
        }
        str++;
    }
}
int main()
{
    int pp=0;
    scanf("%d",&n);
    tot=0;
    fail[0]=-1;
    for(int i=1; i<=n; i++)
    {
        scanf("%s",a);
        Trie_creat(a,i);
    }
    init_fail();
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        bp=0;
        scanf("%s",a);
        memset(vis,0,sizeof(vis));
        AC_automation(a);
        if(bp>0)
        {
            sort(ans,ans+bp);
            printf("web %d:",i);
            for(int i=0;i<bp;i++)
            {
                printf(" %d",ans[i]);
            }printf("\n");
            pp++;
        }
    }printf("total: %d\n",pp);
}

位运算加速的gcd:

 

int gcd(int a,int b)
{
    while(b^=a^=b^=a%=b);
    return a;
}


网络流模板:

#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm> 
#include<iostream>
#include<cstdio>
#define For(a,b,c) for(a=b;a<=c;a++)
#include<queue>
#define inf 999999999
using namespace std;
const int maxn = 1010;
int rong[510][510],liu[510][510];
int p[maxn];
int m,n;
int pre[maxn];
int sum;
void internet(){
    queue<int> q;
    while(1){//不断通过bfs来找增光路,然后ans+=增光路上的流量。
        int i,j;
        memset(p,0,sizeof(p));
        p[1]=inf;//这里的p数组有两个作用,一是用来标记是非访问过,其次是用来记增广路上的瓶颈。
        q.push(1);
        while(!q.empty()){
            int ans=q.front();
            q.pop();
            For(i,1,n){
                if(!p[i]&&liu[ans][i]<rong[ans][i]){
                    p[i]=min(p[ans],rong[ans][i]-liu[ans][i]);
                    pre[i]=ans;//记录增广路。
                    q.push(i);
                }
            }
        }
        if(!p[n]){
            break;//如果n点找不到增光路,说明已经没增广路到汇点了。
        }
        sum+=p[n];
        int tmp=n;
        while(pre[tmp]){//不断调整流量大小。
            liu[pre[tmp]][tmp]+=p[n];
            liu[tmp][pre[tmp]]-=p[n];
            tmp=pre[tmp];
        }
    }
}
int main(){
    int i,j,k;
    int x,y,z;

    while(scanf("%d%d",&m,&n)!=EOF){
        sum=0;
        memset(pre,0,sizeof(pre));
        memset(rong,0,sizeof(rong));
        memset(liu,0,sizeof(liu));
        For(i,1,m){
            scanf("%d%d%d",&x,&y,&z);
            rong[x][y]+=z;
        }
        internet();
        printf("%d\n",sum);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值