模板库

前言

这篇博客长期不更新,主要归纳一下最近的算法(模板),欢迎大家补充。

- 数据结构

  • RMQ(区间最大)
int n,m;
int f[N][21];
void rmq()
{
     for(int i=1;i<=n;i++) f[i][0]=a[i];
     int l=trunc(log2(n));
     for(int j=1;j<=l;j++)
     {
          for(int i=1;i<=n+1-(1<<j);i++)
          f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
     }
}
int rmqmax(int l,int r)
{
    int m=int(trunc(log2(r-l+1)));
    return max(f[l][m],f[r-(1<<m)+1][m]);
}
  • 二维rmq
int rmq[11][11][N][N];
int n,m;
void pre()
{
    fo(i,1,n)
    fo(j,1,m) rmq[0][0][i][j]=f[i][j];
    int p=int(log2(n)),q=int(log2(m));
    fo(k,0,p)
    fo(l,0,q)
    if(k+l)
    fo(i,1,n-(1<<k)+1)
    fo(j,1,m-(1<<l)+1)
    if (!l) rmq[k][l][i][j]=max(rmq[k-1][l][i][j],rmq[k-1][l][i+(1<<(k-1))][j]);
    else rmq[k][l][i][j]=max(rmq[k][l-1][i][j],rmq[k][l-1][i][j+(1<<(l-1))]);
    }
}
int rmqmax(int x1,int y1,int x2,int y2)
{
    int p=int(log2(x2-x1+1)),q=int(log2(y2-y1+1));
    int m1=rmq[p][q][x1][y1];
    int m2=rmq[p][q][x2-(1<<p)+1][y1];
    int m3=rmq[p][q][x1][y2-(1<<q)+1];
    int m4=rmq[p][q][x2-(1<<p)+1][y2-(1<<q)+1];
    return max(max(m1,m2),max(m3,m4));
}
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 90010
#define inf 1000000000
using namespace std;
int w[N];
int to[N],next[N],last[N],num=0;
int dep[N],siz[N];
int top[N],son[N];
int fa[N];
int pos[N],z[N];
struct node{
    int s,mx;
}tr[N*4];
void link(int x,int y)
{
    num++;
    to[num]=y;
    next[num]=last[x];
    last[x]=num;
}
void find(int x)
{
    siz[x]=1;son[x]=0;
    for(int i=last[x];i;i=next[i])
    {
        int v=to[i];
        if(v!=fa[x])
        {
            dep[v]=dep[x]+1;
            fa[v]=x;
            find(v);
            if(siz[v]>siz[son[x]]) son[x]=v;
            siz[x]+=siz[v];
        }
    }
}
int cnt=0;
void dfs(int x,int t)
{
    pos[x]=++cnt;
    top[x]=t;
    z[pos[x]]=x;
    if(son[x]) dfs(son[x],t);
    for(int i=last[x];i;i=next[i])
    {
        int v=to[i];
        if(v!=fa[x] && v!=son[x])
        dfs(v,v);
    }
}
void build(int v,int l,int r)
{
    if(l==r)
    {
        tr[v].s=tr[v].mx=w[z[l]];
        return;
    }
    int mid=(l+r)/2;
    build(v*2,l,mid);
    build(v*2+1,mid+1,r);
    tr[v].s=tr[v*2].s+tr[v*2+1].s;
    tr[v].mx=max(tr[v*2].mx,tr[v*2+1].mx);
}
void change(int v,int l,int r,int x,int p)
{
    if(l==r && l==x)
    {
        tr[v].s=tr[v].mx=p;
        return;
    }
    int mid=(l+r)/2;
    if(x<=mid) change(v*2,l,mid,x,p);
    else change(v*2+1,mid+1,r,x,p);
    tr[v].s=tr[v*2].s+tr[v*2+1].s;
    tr[v].mx=max(tr[v*2].mx,tr[v*2+1].mx);
}
int qsum(int v,int l,int r,int x,int y)
{
    if(l==x && r==y) return tr[v].s;
    int mid=(l+r)/2;
    if(y<=mid) return qsum(v*2,l,mid,x,y);
    else if(x>mid) return qsum(v*2+1,mid+1,r,x,y);
    else return qsum(v*2,l,mid,x,mid)+qsum(v*2+1,mid+1,r,mid+1,y);
}
int qmax(int v,int l,int r,int x,int y)
{
    if(l==x && r==y) return tr[v].mx;
    int mid=(l+r)/2;
    if(y<=mid) return qmax(v*2,l,mid,x,y);
    else if(x>mid) return qmax(v*2+1,mid+1,r,x,y);
    else return max(qmax(v*2,l,mid,x,mid),qmax(v*2+1,mid+1,r,mid+1,y));
}
int findmax(int u,int v)
{
    int f1=top[u],f2=top[v];
    int tmp=-inf;
    while(f1!=f2)
    {
        if(dep[f1]<dep[f2])
        {
            swap(f1,f2);
            swap(u,v);
        }
        tmp=max(tmp,qmax(1,1,cnt,pos[f1],pos[u]));
        u=fa[f1];
        f1=top[u];
    }
    if(dep[u]>dep[v]) swap(u,v); 
    return max(tmp,qmax(1,1,cnt,pos[u],pos[v]));
}
int findsum(int u,int v) 
{
    int f1=top[u],f2=top[v];
    int tmp=0;
    while(f1!=f2)
    {
        if(dep[f1]<dep[f2])
        {
            swap(f1,f2);
            swap(u,v);
        }
        tmp+=qsum(1,1,cnt,pos[f1],pos[u]);
        u=fa[f1];
        f1=top[u];
    }
    if(dep[u]>dep[v]) swap(u,v);
    return tmp+qsum(1,1,cnt,pos[u],pos[v]);
}
int main()
{
    int n;
    cin>>n;
    fo(i,1,n-1)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        link(x,y);
        link(y,x);
    }
    fo(i,1,n) scanf("%d",&w[i]);
    find(1);
    dfs(1,1);
    build(1,1,cnt);
    int Q;
    cin>>Q;
    while(Q--)
    {
        char s[11];
        scanf("%s",s);
        if(s[0]=='C')
        {
            int x,t;
            scanf("%d %d",&x,&t);
            change(1,1,cnt,pos[x],t);
        }
        else
        {
            int x,y;
            scanf("%d %d",&x,&y);
            if(s[1]=='M') printf("%d\n",findmax(x,y));
            else printf("%d\n",findsum(x,y));
        }
    }
}

-图论

  • 网络流(GAP)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define N 1001
#define M 500001
using namespace std;
int f[1001][1001];
int h[1001],vh[1001];
int n,m;
int dfs(int x,int y)
{
    if(x==m) return y;
    int minh=m+1;
    for(int i=1;i<=m;i++)
    if(f[x][i]>0)
    {
        if(h[x]==h[i]+1)
        {
            int t=dfs(i,min(y,f[x][i]));
            if(t>0)
            {
                f[x][i]-=t;
                f[i][x]+=t;
                return t;
            }
        }
        minh=min(minh,h[i]+1);
        if(h[1]>m) return 0;
    }
    vh[h[x]]--;
    if(vh[h[x]]==0) h[1]=m+1;
    h[x]=minh;
    vh[h[x]]++;
    return 0;
}
int main()
{    
    vh[0]=m;
    while(h[1]<=m) ans+=dfs(1,2147483647);
    cout<<ans;
}
  • 网络流(Dinic)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int p[100001];
int g[400001],next[400001],last[400001];
int f[400001],h[200001],d[400001];
int n,m;
int s=1,t;
int num=1;
int ins(int x,int y,int c)
{
    num++;
    g[num]=y;
    next[num]=last[x];
    last[x]=num;
    f[num]=c;
}
bool bfs()
{
    memset(h,0,sizeof(h));
    int x=0,y=1;
    d[1]=1;
    h[1]=1;
    while(x<y)
    {
        x++;
        for(int i=last[d[x]];i>0;i=next[i])
        {
            if(f[i] && h[g[i]]==0)
            {
                d[++y]=g[i];
                h[g[i]]=h[d[x]]+1;
            }   
        }
    }
    return h[t];
}
int dfs(int x,int y)
{
    int sum=0;
    if(x==t) return y;
    for(int i=last[x];i>0;i=next[i])
    {
        if(h[x]+1==h[g[i]] && f[i])
        {
            int tmp=dfs(g[i],min(y,f[i]));
            if(tmp>0)
            {
                f[i]-=tmp;
                int T;
                if(i%2==0) T=i+1;
                else T=i-1;
                f[T]+=tmp;
                y-=tmp;
                sum+=tmp;
                if(!y) break;
            }
        }
    }
    if(!sum) h[x]=-1;//大优化
    return sum;
}
int main()
{
    int ans=0;
    while(bfs()) ans+=dfs(s,2147483647);
}

- 字符串

  • kmp
int f[N];
void get(char *s)
{
    int j=0;
    fo(i,2,strlen(s+1))
    {
        while(j>0 && s[j+1]!=s[i]) j=f[j];
        if (s[j+1]==s[i]) j++;
        f[i]=j;
    }
}
int kmp(char *s1,char *s2)
{
    int j=0;
    int ans=0;
    int l1=strlen(s1),l2=strlen(s2);
    fo(i,1,l1)
    {
        while (j>0 && s2[j+1]!=s1[i]) j=f[j];
        if (s2[j+1]==s1[i]) j++;
        if (j==l2) 
        {
            ans++;
            j=f[j];
        }
    }
    return ans;
}

留坑~

posted @ 2016-06-30 19:04  sadstone  阅读(49)  评论(0编辑  收藏  举报