zoukankan      html  css  js  c++  java
  • SPOJ 8093 JZPGYZ

    思路

    可以用复杂度不对的做法水过去
    相当于求parent树子树中的颜色种数,可以离线后树状数组(HH的项链,询问右端点排序之后维护last),dsu on tree,莫队都可以
    但是也可以记录每个点上次被更新的原串(last[i]),然后通过fail向上更新

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <bits/stdc++.h>
    using namespace std;
    int Nodecnt=1,trans[200000][26],suflink[200000],sz[200000],last[200000],maxlen[200000],n,m;
    char s[200000];
    int New_state(int _maxlen,int _sz,int *_trans,int _suflink,int _last){
        ++Nodecnt;
        sz[Nodecnt]=_sz;
        if(_trans)
            for(int i=0;i<26;i++)
                trans[Nodecnt][i]=_trans[i];
        suflink[Nodecnt]=_suflink;
        last[Nodecnt]=_last;
        maxlen[Nodecnt]=_maxlen;
        return Nodecnt;
    }
    inline void update(int u,int x){
        while(u&&last[u]!=x){
            sz[u]++;
            last[u]=x;
            u=suflink[u];
        }
    }
    int add_len(int u,int c,int inq){
        if(trans[u][c]){
            int v=trans[u][c];
            if(maxlen[v]==maxlen[u]+1){
                update(v,inq);
                return v;
            }
            int y=New_state(maxlen[u]+1,sz[v],trans[v],suflink[v],last[v]);
            suflink[v]=y;
            while(u&&trans[u][c]==v){
                trans[u][c]=y;
                u=suflink[u];
            }
            update(y,inq);
            return y;
        }
        else{
            int z=New_state(maxlen[u]+1,0,NULL,0,0);
            while(u&&trans[u][c]==0){
                trans[u][c]=z;
                u=suflink[u];
            }
            if(!u){
                suflink[z]=1;
                update(z,inq);
                return z;
            }
            int v=trans[u][c];
            if(maxlen[v]==maxlen[u]+1){
                suflink[z]=v;
                update(z,inq);
                return z;
            }
            int y=New_state(maxlen[u]+1,sz[v],trans[v],suflink[v],last[v]);
            suflink[v]=suflink[z]=y;
            while(u&&trans[u][c]==v){
                trans[u][c]=y;
                u=suflink[u];
            }
            update(z,inq);
            return z;
        }
    }
    int query(char *s,int len){
        int o=1;
        for(int i=1;i<=len;i++){
            o=trans[o][s[i]-'a'];
        }
        return sz[o];
    }
    int main(){
        freopen("test.in","r",stdin);
        freopen("test.out","w",stdout);
        scanf("%d %d",&n,&m);
        Nodecnt=1;
        for(int i=1;i<=n;i++){
            scanf("%s",s+1);
            int len=strlen(s+1),last=1;
            for(int j=1;j<=len;j++)
                last=add_len(last,s[j]-'a',i);
        }
        sz[0]=0;
        for(int i=1;i<=m;i++){
            scanf("%s",s+1);
            int len=strlen(s+1);
            printf("%d
    ",query(s,len));
        }
        return 0;
    }
    
  • 相关阅读:
    Django框架基础之序列化
    资产采集
    CMDB
    数据库--三层架构
    Django 项目一补充
    评论楼
    图片预览
    验证码
    如何使用C/C++动态库与静态库中的宏
    Matlab 直线方程、采样函数
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10717958.html
Copyright © 2011-2022 走看看