zoukankan      html  css  js  c++  java
  • 【BZOJ2780】Sevenk Love Oimaster(广义后缀自动机)

    点此看题面

    大致题意: 给定(n)个模式串,每次询问一个串是多少模式串的子串。

    关于(AC)自动机

    (n)个模式串?多模匹配问题,显然要上(AC)自动机嘛!

    实际上这题也的确可以用(AC)自动机做,这里给出一个此题加强版的链接【BZOJ3881】[COCI2015] Divljak(AC自动机+树状数组)

    不过,由于是在复习后缀自动机,还是决定用后缀自动机写一写这道题。

    广义后缀自动机

    考虑我们对这(n)个串建后缀自动机,然后对于每一个串,枚举其节点暴力往上跳,给沿途所有点打标记,遇到打过当前串标记的节点就退掉,由于每个串每个点只会被打一次标记,复杂度是正确的。

    询问就是询问串在后缀自动机上对应节点被打标记的次数。

    发现自己写法居然和bzt惊人相似,好荣幸啊!

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 10000
    #define LEN 100000
    #define MAX 360000
    using namespace std;
    int n,l[N+5];char s[LEN+5],ss[MAX+5];
    class SuffixAutomation
    {
    	private:
    		int Nt,lst;struct node {int C,V,L,F,S[30];}O[LEN<<1];
    	public:
    		I SuffixAutomation() {Nt=1;}I void Init() {lst=1;}//广义后缀自动机
    		I void Ins(CI x,CI ti)//插入新字符
    		{
    			RI p=lst,now=lst=++Nt;O[now].L=O[p].L+1;
    			W(p&&!O[p].S[x]) O[p].S[x]=now,p=O[p].F;if(!p) return (void)(O[now].F=1);
    			RI q=O[p].S[x];if(O[p].L+1==O[q].L) return (void)(O[now].F=q);
    			RI k=++Nt;(O[k]=O[q]).L=O[p].L+1,O[now].F=O[q].F=k;
    			W(p&&O[p].S[x]==q) O[p].S[x]=k,p=O[p].F;
    		}
    		I void Work(char *s,CI ti)//统计信息
    		{
    			RI i,p=1,x;for(i=1;i<=l[ti];++i)//枚举点
    				{x=p=O[p].S[s[i]&31];W(x&&O[x].V^ti) O[x].V=ti,++O[x].C,x=O[x].F;}//暴力上跳打标记
    		}
    		I void Solve(char *s)//求解答案
    		{
    			RI p=1;for(RI i=1,l=strlen(s+1);p&&i<=l;++i) p=O[p].S[s[i]&31];//找到对应点
    			printf("%d
    ",O[p].C);//返回打标记次数
    		}
    }S;
    int main()
    {
    	RI Qt,i,j,tot=0;for(scanf("%d%d",&n,&Qt),i=1;i<=n;++i)//枚举模式串
    	{
    		S.Init(),scanf("%s",s+tot+1),l[i]=strlen(s+tot+1);
    		for(j=1;j<=l[i];++j) S.Ins(s[tot+j]&31,i);tot+=l[i];//建后缀自动机
    	}
    	for(tot=0,i=1;i<=n;++i) S.Work(s+tot,i),tot+=l[i];//维护好信息
    	W(Qt--) scanf("%s",ss+1),S.Solve(ss);return 0;//处理询问
    }
    
  • 相关阅读:
    ie调试器
    修改tomcat的部署名称
    Hibernate级联操作
    eclipse 批量 查询 替换
    Hibernate包及相关工具包下载地址
    new Option及用法
    java字符串的判断
    Caused by: java.lang.ClassNotFoundException: javax.persistence.EntityListeners
    【微信公众平台开发】创建自己定义菜单(四)
    fastjson 的简单使用
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2780.html
Copyright © 2011-2022 走看看