• 洛谷 SP8093 JZPGYZ


    传送门
    对于给定的串建广义后缀自动机,然后标记每个点所代表的字符串属于多少串,这个标记方式和之前的那道最长公共子串的匹配方式有些像,可以这样理解,枚举这个字符串的前缀,然后将这个前缀的所有后缀都标记上,就是将所有子串都标记了。这个也是后面才理解到的,SAM 的性质实在太神奇了。
    然后匹配就不用细说了,就是沿着 DAG 跑,如果字符串没跑完 DAG 就跑不动了,答案当然就是 0,如果跑完了,答案就是目前 DAG 节点上的标记值。
    这个代码的广义SAM写法有些问题,应该判断想插入的节点是否存在的问题,之后有正确的写法。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=1e5+10;
    int n,m,tlen;
    string s[N],t;
    struct SuffixAutoMachine{
    	int last=1,tot=1,fa[N*2],ch[N*2][26],len[N*2],f[N*2],vis[N*2];
    	int newnode(int x){fa[++tot]=fa[x];len[tot]=len[x];memcpy(ch[tot],ch[x],sizeof(ch[tot]));return tot;}
    	void append(int c){
    		int p=last,np=last=newnode(0);
    		len[np]=len[p]+1;
    		for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    		if(!p) {fa[np]=1;return;}
    		int q=ch[p][c];
    		if(len[q]==len[p]+1) {fa[np]=q;return;}
    		int nq=newnode(q);len[nq]=len[p]+1;
    		fa[q]=fa[np]=nq;
    		for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq; 
    	}
    	void insert(string s){
    		last=1;
    		for(int i=0;i<s.size();i++) append(s[i]-'a');
    	}
    	void update(int p,int id){
                    //这里就是在枚举p所代表的子串的后缀,vis可以加快速度
    		for(;p&&vis[p]<id;p=fa[p]) f[p]++,vis[p]=id;
    	}
    	void match(string s){
    		bool flag=true;
    		int p=1;
    		for(int i=0;i<s.size();i++)
    			if(ch[p][s[i]-'a']) p=ch[p][s[i]-'a'];
    			else {flag=false;break;}
    		printf("%d
    ",flag?f[p]:0);
    	}
    }sam;
    
    
    int main(){
    	ios::sync_with_stdio(false);cin.tie(0);
    	cin>>n>>m;
    	for(int i=1;i<=n;i++) cin>>s[i],sam.insert(s[i]);
    	for(int i=1;i<=n;i++)
    		for(int j=0,p=1;j<s[i].size();j++) 
                            //这个操作其实就是枚举s的所有前缀,扔到update里去枚举前缀的后缀
    			sam.update(p=sam.ch[p][s[i][j]-'a'],i);
    	for(int i=1;i<=m;i++){
    		cin>>t;
    		sam.match(t);
    	}
    	return 0;
    }
    
  • 相关阅读:
    BZOJ 4025: 二分图
    20180803 题解 Winniechen's Tesst
    前尘浮华一场梦 NOI2018 游记
    UOJ#311. 【UNR #2】积劳成疾
    欢迎到我的新Blog!
    弹飞大爷 BZOJ4764 LCT维护内向基环树森林
    [SCOI2007]修车 BZOJ1070
    KD-Tree
    CDQ分治
    深入解析DC/OS 1.8 – 高可靠的微服务及大数据管理平台
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12670833.html
Copyright © 2020-2023  润新知