ACM模版——数据结构

//===========================================\\

KMP算法                                  |

\\===========================================//

char p[10010],t[1000010];

int  next[10010],lp,lt;  // lp为p长度,lt为t长度

void getnext()

{

    int i=0,j=-1;

    next[0]=-1;

    while ( i<lp )

    {

        if ( j==-1 || p[i]==p[j] )

        {

            i++; j++;

            if ( p[i]==p[j] ) next[i]=next[j];

            else next[i]=j;

        }

        else j=next[j];

    }

}

int kmp()

{

    int i=0,j=0,ans=0;

    getnext();

    while ( i<lt && j<lp )

    {

        if ( j==-1 || t[i]==p[j] ){  i++; j++; }

        else j=next[j];

        if ( j==lp )

        {

            //  位置: x0=i-j

            ans++;

            j=next[j];

        }

    }

    return ans;

}

//===========================================\\

BM算法                                   |

\\===========================================//

char p[10010],t[1000010];

int suff[10010],good[10010],Asc[256];

int ans,lenp,lent;

void getgood()

{

    int i,j,f;

    suff[lenp-1]=lenp;  // 求suff

    j=lenp-1;

    for ( i=lenp-2; i>=0; i--)

    {

        if ( i>j && suff[i+lenp-1-f]<i-j )

            suff[i]=suff[i+lenp-1-f];

        else

        {

            if ( i<j ) j=i;

            f=i;

            while ( j>=0 && p[j]==p[j+lenp-1-f]) j--;

            suff[i]=f-j;

        }

    }

   for ( i=0; i<lenp; i++ ) good[i]=lenp;  //求good

   for ( i=lenp-1; i>=0; i--)

       if ( suff[i]==i+1 )  //p不含已匹配串

           for ( ; j<lenp-1-i; j++)

               if ( good[j]==lenp ) good[j]=lenp-1-i;

   for ( i=0; i<=lenp-2; i++)

       good[lenp-1-suff[i]]=lenp-1-i; //p中含匹配串

}

void getbad()

{

    memset(Asc,0xff,sizeof(Asc));

    for (int i=0; i<lenp; i++) Asc[p[i]]=i;

}

void bm()

{

    getgood();

    getbad();

    int i,j=0,k=0;

    ans=0;

    while ( j<=lent-lenp )

    {

        for ( i=lenp-1; i>=k && p[i]==t[i+j]; i-- );

        if ( i<k )

        { 

            // 位置:output(j);

            ans++;

            j+=good[0];

            k=lenp-good[0];

        }

        else if ( Asc[t[j+lenp]]==-1 ) j+=lenp+1;

        else

        {

            k=0;

            if ( good[i]<i-Asc[t[i+j]] ) j+=i-Asc[t[i+j]];

            else

            {

                j+=good[i];

                if ( i<good[i] ) k=lenp-good[i];

                else k=0;

            }

        }

    }

}

//===========================================\\

|                                          |

\\===========================================//

int s[1000000],clu;

bool cmp(int a,int b)  //小根堆

{

    return a>b;

}

void make()  //make_heap(s+1,s+clu+1,cmp);

{

    for (int j=clu/2; j>=1; j--)

    {

        int i=j,k,t=s[i];

        while ( i*2<clu )

        {

            i*=2;

            if ( i+1<clu && s[i+1]<s[i] ) k=s[++i];

            else k=s[i];

            if ( k<t ) s[i/2]=s[i];

            else { i/=2; break; }

        }

        s[i]=t;

    }

}

void insert(int x) //push_heap(s+1,s+clu+1,cmp);

{

    int i=++clu;

    while ( i!=1 && s[i/2]<x )

    {

        s[i]=s[i/2];

        i/=2;

    }

    s[i]=x;

}

void del() //pop_heap(s+1,s+clu+1,cmp);

{

    int i=1,j;

    while ( i*2<clu )

    {

        i*=2;

        if ( i+1<clu && s[i+1]<s[i] ) j=s[++i];

        else j=s[i];

        if ( j<s[clu] ) s[i/2]=s[i];

        else { i/=2; break;}

    }

    s[i]=s[clu--];

}

//===========================================\\

|     并查集                                 |

\\===========================================//

int g[10000],r[10000];  //初始化g[i]=r[i]=i;

void update(int a,int b)

{

    int i=g[b],j=r[g[a]];

    r[g[a]]=g[b];

    while ( r[i]!=i )

    {

        g[i]=g[a];

        i=r[i];

    }

    g[i]=g[a];

    if ( j!=g[a] ) r[i]=j;

}

//===========================================\\

|     树状数组                               |

\\===========================================//

int a[100000],tr[100000],n;

int Lowbit(int t) { return t^(t-1)&t; }

int Sum(int end)

{

    int ans=0;

    while ( end ) { ans+=tr[end]; end-=Lowbit(end); }

    return ans;

}

void update(int pos,int num)

{

    int j=num-a[pos];

    a[pos]=num;

    while ( pos<=n ) { tr[pos]+=j; pos+=Lowbit(pos); }

}

 

//===========================================\\

|     二维树状数组                           |

\\===========================================//

int a[10000][10000],tr[10000][10000],row,col;

int Lowbit(int t) { return t^(t-1)&t; }

int Sum(int i,int j)

{

    int k,ans=0;

    while ( i )

    {

        k=j;

        while ( k ) { ans+=tr[i][k]; k-=Lowbit(k); }

        i-=Lowbit(i);

    }

    return ans;

}

void update(int i,int j,int num)

{

    int j=num-a[i][j],k;

    a[i][j]=num;

    while ( i<=row )

    {

        k=j;

        while ( k<=col ) { tr[i][k]+=j; k+=Lowbit(k); }

        i+=Lowbit(i);

    }

}

//===========================================\\

|     SBT                                    |

\\===========================================//

struct SBT

{

    int x,s,l,r; //key,size,left,right

    int note; //附加信息

}tr[1000];

int stack[1000],end; // 回收删除的节点

int root,top; //树根节点、预置空间定位

void Rro(int &root) //右旋

{

    int k=tr[root].l;

    tr[root].l=tr[k].r;

    tr[k].r=root;

    tr[k].s=tr[root].s;

    tr[root].s=tr[tr[root].l].s+tr[tr[root].r].s+1;

    root=k;

}

void Lro(int &root) //左旋

{

    int k=tr[root].r;

    tr[root].r=tr[k].l;

    tr[k].l=root;

    tr[k].s=tr[root].s;

    tr[root].s=tr[tr[root].l].s+tr[tr[root].r].s+1;

    root=k;

}

void sb(int &root,bool flag) //平衡函数

{

    if ( !flag ) //插入到左边

    {

        if ( tr[tr[tr[root].l].l].s>tr[tr[root].r].s ) Rro(root);

        else if ( tr[tr[tr[root].l].r].s>tr[tr[root].r].s )

        {

            Lro(tr[root].l);

            Rro(root);

        }

        else return;

    }

    else //插入到右边

    {

        if ( tr[tr[tr[root].r].r].s>tr[tr[root].l].s ) Lro(root);

        else if ( tr[tr[tr[root].r].l].s>tr[tr[root].l].s )

        {

            Rro(tr[root].r);

            Lro(root);

        }

        else return;

    }

    sb(tr[root].l,false);

    sb(tr[root].r,true);

    sb(root,true);

    sb(root,false);

}

void insert(int &root,int x,int note)

{

    if ( root==0 )

    {

        if ( end>0 ) root=stack[--end];

//优先实用回收站的节点

        else root=++top;

        tr[root].x=x;

        tr[root].s=1;

        tr[root].r=tr[root].l=0;

        tr[root].note=note;

    }

    else

    {

        tr[root].s++;

        if ( x<tr[root].x ) insert(tr[root].l,x,note);

        else insert(tr[root].r,x,note);

        sb(root,x>=tr[root].x);

    }

}

int del(int &root,int x) //删除,stack[end++]=del()

{

    tr[root].s--;

    if ( x<tr[root].x ) del(tr[root].l,x);

    else if ( x>tr[root].x ) del(tr[root].r,x);

    else

    {

        if ( tr[root].l==0 || tr[root].r==0 )

        {

            int t=root;

            root=tr[root].l+tr[root].r;

            return t;

        }

        else

        {

            int t=tr[root].r;

            while ( tr[t].l!=0 ) t=tr[t].l;

            tr[root].x=tr[t].x;

            del(tr[root].r,tr[root].x);

        }

    }

}

int sr(int root,int x) //查找x的位置

{

    if ( x>tr[root].x && tr[root].r!=0 ) return sr(tr[root].r,x);

    else if ( x<tr[root].x && tr[root].l!=0 ) return sr(tr[root].l,x);

    else return root;

}

int pred(int root,int y,int x) //小于(等于)x的最大数

// 调用时 pred(root,0 ,x),空树返回0,后继也是

{

    if ( root==0 ) return y;

    if ( x>tr[root].x ) //加上等号,就是小于等于

        return pred(tr[root].r,root,x);

    else return pred(tr[root].l,y,x);

}

int succ(int root,int y,int x) //大于(等于)x的最小数

{

    if ( root==0 ) return y;

    if ( x<tr[root].x ) return succ(tr[root].l,root,x);

    else return succ(tr[root].r,y,x);

}

int rank(int root,int x) // x的升序排名

{

    if ( root==0 ) return 1;

    else if ( x>tr[root].x ) return rank(tr[root].r,x)+tr[tr[root].l].s+1;

    else return rank(tr[root].l,x);

}

int select(int root,int k) //找第k小的元素

{

    if ( k==tr[tr[root].l].s+1 ) return root;

    else if ( k<=tr[tr[root].l].s ) return select(tr[root].l,k);

    else return select(tr[root].r,k-tr[tr[root].l].s-1);

}

int getmin(int root) //最小值

{

    while ( tr[root].l ) root=tr[root].l;

    return tr[root].x;

}

int geimax(int root) //最大值

{

    while ( tr[root].r ) root=tr[root].r;

    return tr[root].x;

}

//===========================================\\

|     线段树                                 |

\\===========================================//

struct seg_tree

{

    int l,r;

    int sum,mim,max,x;

}tr[100];

void build(int l,int r,int p) //建树,并初始化

{

    if ( l==r )

    {

        tr[p].l=tr[p].r=l;

        // sum=min=max=x=?

    }

    else

    {

        tr[p].l=l;

        tr[p].r=r;

        build(l,(l+r)/2,p*2);

        build((l+r)/2+1,r,p*2+1);

        // sum,min,max=?

    }

}

void pushdown(int p) // 标记下传框架

{

    tr[p*2].m+=tr[p].m;

    tr[p*2].max+=tr[p].m;

    tr[p*2+1].m+=tr[p].m;

    tr[p*2+1].max+=tr[p].m;

    tr[p].m=0;

}

void update(int p) // 更新框架

{

    if ( tr[p*2].max>=tr[p*2+1].max )

    {

        tr[p].max=tr[p*2].max;

        tr[p].id=tr[p*2].id;

    }

    else

    {

        tr[p].max=tr[p*2+1].max;

        tr[p].id=tr[p*2+1].id;

    }

}

void query(int l,int r,int p) //查询区间框架

{

    if ( l<=tr[p].l && tr[p].r<=r )

    {

        ...... // 根据标记,更新结果

        return;

    }

    Push_Down(p);

    int mid=(tr[p].l+tr[p].r)/2;

    if ( l<=mid ) query(l,r,p*2);

    if ( r>mid ) query(l,r,p*2+1);

    // 有时候需要汇总

}

void change(int l,int r,int p) //修改区间框架

{

    if ( l<=tr[p].l && tr[p].r<=r )

    {

        ...... // 修改当前结点信息,并标上标记

        return;

    }

    Push_Down(p);

    int mid=(tr[p].l+tr[p].r)/2;

    if ( l<=mid ) change(l,r,p*2);

    if ( r>mid ) change(l,r,p*2+1);

    Update(p); //维护当前结点信息(子结点可能被修改)

}

//===========================================\\

|     字符哈希                               |

\\===========================================//

int BKDR(char *s) 

    unsigned long h=0,g=131; // 31,131,1313,13131..

    while ( *s ) h=h*g+*s++; 

    return h%10007; // 根据实际要求取模

}

int ELF(char *s)

{

    unsigned long h=0;

    while ( *s )

    {

        h=(h<<4)+*s++;

        unsigned long g=h & 0Xf0000000L;

        if ( g ) h^=g>>24;

        h&=~g;

    }

    return h%10007;

}

posted @ 2012-09-22 13:44  枫落丹寒  阅读(172)  评论(0)    收藏  举报