BZOJ 3796: Mushroom追妹纸 后缀自动机+拓扑排序+DP

本文介绍了一种使用后缀自动机和拓扑排序动态规划解决字符串匹配问题的独特方法。通过构建广义后缀自动机并标记节点,实现了对三个字符串的高效匹配分析。文章详细解释了如何正确识别危险节点,并提供了完整的代码实现。

就是喜欢后缀自动机,yy了一个只用后缀自动机解决的方法.   

对 3 个串建立广义后缀自动机,然后建立后缀树.  

标记出每个点在0/1/2个串中是否作为子串出现,然后将后缀树中 2 串结尾的所有子树都设为危险节点.  

然后对于 SAM 来一个拓扑序DP,我们开始的时候默认危险节点的最大值是 -inf,然后 2 结尾节点最大值为 len(2)-1.  

然后这么转移一下就好了. 

最开始错误的原因误以为只要一个节点会从一个危险节点转移,那么该节点就是危险节点.    

这个是错误的,而是要满足转移过来的节点全是危险节点,这个点才是危险节点. 

code: 

#include <cstdio> 
#include <string>
#include <algorithm>  
#include <queue>
#include <cstring>  
#define N 300006 
#define inf 1000000000 
using namespace std;   
void setIO(string s) 
{
    freopen((s+".in").c_str(),"r",stdin);  
    // freopen((s+".out").c_str(),"w",stdout); 
}
char S[N];  
queue<int>que;  
int edges,dfn,ans,dp[N];  
int ch[N][26],mx[N],pre[N],last,tot,tag[N][3],hd[N],to[N],nex[N],st[N],ed[N],is[N],deg[N];   
void add(int u,int v) 
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
}
void extend(int c,int id) 
{ 
    if(ch[last][c]) 
    {
        int p=last,q=ch[last][c];   
        if(mx[q]==mx[p]+1)  last=q;   
        else 
        {
            int nq=++tot;   
            mx[nq]=mx[p]+1;   
            memcpy(ch[nq],ch[q],sizeof(ch[nq]));   
            pre[nq]=pre[q],pre[q]=nq;   
            for(;p&&ch[p][c]==q;p=pre[p]) ch[p][c]=nq;   
            last=nq; 
        }
    }  
    else 
    {
        int np=++tot,p=last; 
        mx[np]=mx[p]+1,last=np; 
        for(;p&&!ch[p][c];p=pre[p]) ch[p][c]=np;  
        if(!p) pre[np]=1; 
        else 
        {
            int q=ch[p][c]; 
            if(mx[q]==mx[p]+1)  pre[np]=q;  
            else 
            {
                int nq=++tot; 
                mx[nq]=mx[p]+1;   
                memcpy(ch[nq],ch[q],sizeof(ch[q]));    
                pre[nq]=pre[q],pre[q]=pre[np]=nq;     
                for(;p&&ch[p][c]==q;p=pre[p])  ch[p][c]=nq;  
            }
        }
    }      
    tag[last][id]=1;  
}    
void dfs(int u) 
{ 
    st[u]=++dfn; 
    for(int i=hd[u];i;i=nex[i]) 
    {
        int v=to[i]; 
        dfs(v);   
        tag[u][0]|=tag[v][0]; 
        tag[u][1]|=tag[v][1]; 
        tag[u][2]|=tag[v][2];  
    }
    ed[u]=dfn;  
}           
int main() 
{ 
    // setIO("input"); 
    last=tot=1;
    int i,j,len,cor; 
    for(scanf("%s",S+1),len=strlen(S+1),last=1,i=1;i<=len;++i) extend(S[i]-'a',0);   
    for(scanf("%s",S+1),len=strlen(S+1),last=1,i=1;i<=len;++i) extend(S[i]-'a',1);              
    for(scanf("%s",S+1),len=strlen(S+1),last=1,i=1;i<=len;++i) extend(S[i]-'a',2);    
    for(i=2;i<=tot;++i) add(pre[i],i);          
    dfs(1); 
    if(tag[last][0]&&tag[last][1])  
        ans=len-1;                                    
    for(i=1;i<=tot;++i)  if(st[i]>=st[last]&&ed[i]<=ed[last])  dp[i]=-inf,is[i]=1;  
    dp[last]=len-1;  
    for(i=1;i<=tot;++i)  for(j=0;j<26;++j) if(ch[i][j])  ++deg[ch[i][j]];     
    for(i=1;i<=tot;++i)  if(!deg[i]) que.push(i);       
    while(!que.empty()) 
    {  
        int u=que.front();que.pop();  
        for(int j=0;j<26;++j)  
        {
            int v=ch[u][j]; 
            if(!v) continue;                       
            if(!is[v]) dp[v]=max(dp[v],dp[u]+1);   
            --deg[v];  
            if(!deg[v]) que.push(v); 
        }
    }
    for(i=1;i<=tot;++i)  if(tag[i][0]&&tag[i][1]) ans=max(ans,dp[i]); 
    printf("%d\n",ans);  
    return 0;
}

  

**高校专业实习管理平台设计与实现** 本设计项目旨在构建一个服务于高等院校专业实习环节的综合性管理平台。该系统采用当前主流的Web开发架构,基于Python编程语言,结合Django后端框架与Vue.js前端框架进行开发,实现了前后端逻辑的分离。数据存储层选用广泛应用的MySQL关系型数据库,确保了系统的稳定性和数据处理的效率。 平台设计了多角色协同工作的管理模型,具体包括系统管理员、院系负责人、指导教师、实习单位对接人以及参与实习的学生。各角色依据权限访问不同的功能模块,共同构成完整的实习管理流程。核心功能模块涵盖:基础信息管理(如院系、专业、人员信息)、实习过程管理(包括实习公告发布、实习内容规划、实习申请与安排)、双向反馈机制(单位评价与学生反馈)、实习支持与保障、以及贯穿始终的成绩评定与综合成绩管理。 在技术实现层面,后端服务依托Django框架的高效与安全性构建业务逻辑;前端界面则利用Vue.js的组件化特性与LayUI的样式库,致力于提供清晰、友好的用户交互体验。数据库设计充分考虑了实习管理业务的实体关系与数据一致性要求,并保留了未来功能扩展的灵活性。 整个系统遵循规范的软件开发流程,从需求分析、系统设计、编码实现到测试验证,均进行了多轮迭代与优化,力求在功能完备性、系统性能及用户使用体验方面达到较高标准。 **核心术语**:实习管理平台;Django框架;MySQL数据库;Vue.js前端;Python语言。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
在电磁散射与雷达技术的研究中,涉及粗糙表面电磁特性模拟的核心概念包括统计参数化建模方法、不同电场矢量方向的极化模式、特定方向的能量反射现象、理想化波前模型以及具有随机起伏特征的界面。以下是对这些要点的系统阐述: 统计参数化建模是一种基于表面统计特征描述其不规则性的电磁散射计算方法,尤其适用于均方根高度较小的粗糙界面在微波至毫米波频段的散射特性分析。 水平极化与垂直极化分别指电场矢量平行于地面和垂直于地面的振动状态。在雷达探测中,采用不同的极化模式有助于提升目标辨识度并抑制环境干扰。 当电磁波与物体相互作用时,部分能量沿接近入射方向返回,这种现象称为反向散射。其在雷达系统的探测灵敏度与目标特征分析中具有关键作用。 平面波是在均匀介质中传播的理想波型,其电场与磁场分布保持一致的相位关系,常作为理论简化模型用于电磁问题的解析与数值计算。 粗糙界面指具有随机起伏特征的表面,其不规则程度可通过均方根高度进行量化。这种结构特性会改变电磁波的传播路径与能量分布,进而影响信号的接收与处理。 相关压缩文件可能包含了实现上述建模方法的程序代码,通常采用数值计算语言编写,用于模拟不同极化状态下粗糙表面对平面波的反向散射响应。通过此类仿真,能够预测各类场景下的散射参数,为雷达系统设计与遥感数据解译提供理论依据。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值