【学习笔记】CF1817F Entangled Substrings(基本子串结构)

前置知识:基本子串结构,SAM的结构和应用

学长博客

字符串理论比较抽象,建议直观的去理解它

子串 t t t的扩展串定义为 ext(t) : = t ′ \text{ext(t)}:=t' ext(t):=t,满足 t t t t ′ t' t的子串,且 occ(t) = occ(t’) \text{occ(t)}=\text{occ(t')} occ(t)=occ(t’)

基本性质:若 t = [ l : r ] , t ′ = [ l ′ : r ′ ] t=[l:r],t'=[l':r'] t=[l:r],t=[l:r] t ′ ′ = [ l ′ ′ : r ′ ′ ] t''=[l'':r''] t′′=[l′′:r′′],使得 l ′ ≤ l ′ ′ ≤ l ≤ r ≤ r ′ ′ ≤ r ′ l'\le l''\le l\le r\le r''\le r' ll′′lrr′′r,则 ext(t”) = t ′ \text{ext(t'')}=t' ext(t”)=t

子串 x , y x,y x,y等价当且仅当 ext(x) = ext(y) \text{ext(x)}=\text{ext(y)} ext(x)=ext(y)。然后,记录每个等价类的最长串作为代表元。

s [ l : r ] ↦ ( l , r ) s[l:r]\mapsto (l,r) s[l:r](l,r)的作用下,在 y = x y=x y=x以上的点被等价类划分入若干个阶梯状集合,其中 g \text{g} g对应的阶梯 出现次数 occ(rep(g)) \text{occ(\text{rep(g)})} occ(rep(g))

对于等价类 g g g个某个 完整阶梯,其完整的一行对应的子串集合与 T 0 T_0 T0的某个结点对应的子串集合相同,其完整的一列对应的子串集合与 T 1 T_1 T1(反串对应的后缀树)某个节点对应的子串集合相同,并且一一对应。

定义等价类 g g g的周长为其 一个 完整阶梯的行数列数之和,性质: ∑ g per(g) = O ( n ) \sum_g\text{per(g)}=O(n) gper(g)=O(n)

比较抽象。不是很直观。

如何显式求出这个结构?

第一种方式:对于 T 0 T_0 T0的从父亲到儿子的树边,其从一行的左边界指向另一行的右边界;对于 T 1 T_1 T1的从父亲到儿子的树边,其从一行的上边界连向另一行的下边界。

例如, s = aababcd ‾ s=\underline{\text{aababcd}} s=aababcd,其对应的阶梯划分为:

请添加图片描述
其对应的 S A M SAM SAM T 0 T_0 T0为:

请添加图片描述

其对应的连边为:

请添加图片描述

第二种方式(感觉更常用):对于 D A G DAG DAG上的一条边 ( u , v ) (u,v) (u,v),如果 occ(u) = occ(v) \text{occ(u)}=\text{occ(v)} occ(u)=occ(v),那么就将这条边标记为关键边。

性质:如果只保留关键边,那么每个点入度和出度都至多为一,因此我们得到了若干条关键链。显然,链的末尾就是代表元,一条链就代表了一个等价类

考虑这道题目在让我们干什么:可以发现一个字符串对 ( b 1 , b 2 ) (b_1,b_2) (b1,b2)是好的当且仅当满足以下条件:

1.1 1.1 1.1 b 1 , b 2 b_1,b_2 b1,b2在同一个等价类中
1.2 1.2 1.2 b 1 , b 2 b_1,b_2 b1,b2所在等价类中的代表元为 b b b,那么 b 1 , b 2 b_1,b_2 b1,b2 b b b中出现的位置不交,且 b 1 b_1 b1 b 2 b_2 b2左边

这样,我们对于每个 阶梯状物 统计答案即可。(建议数形结合,以及把下标搞清楚)

代表元的 len \text{len} len实际上表示阶梯状物左上角那个位置的横纵坐标之差。

复杂度 O ( n ) O(n) O(n)

#include<bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
using namespace std;
const int N=2e5+5;
struct node{int to[26],link,len,sz;
}t[N];
int n,cur,last,tot,sz[N];
void extend(int ch){int cur=++tot;t[cur].len=t[last].len+1,t[cur].sz=1;int p=last;while(p!=-1&&!t[p].to[ch]){t[p].to[ch]=cur;p=t[p].link;}if(p!=-1){int q=t[p].to[ch];if(t[q].len==t[p].len+1){t[cur].link=q;}else{int clone=++tot;t[clone].link=t[q].link;for(int i=0;i<26;i++)t[clone].to[i]=t[q].to[i];t[clone].len=t[p].len+1;while(p!=-1&&t[p].to[ch]==q){t[p].to[ch]=clone;p=t[p].link;}t[q].link=t[cur].link=clone;}}last=cur;
}
string str;
int nxt[N],vs[N];
int st[N],cnt;
ll s[N];
ll res;
vector<int>G[N];
void dfs(int u){for(auto v:G[u])dfs(v),t[u].sz+=t[v].sz;
}
int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);t[0].link=-1;cin>>str,n=str.size();for(int i=0;i<n;i++)extend(str[i]-'a');for(int i=1;i<=tot;i++)G[t[i].link].pb(i);dfs(0);for(int i=1;i<=tot;i++){for(int j=0;j<26;j++){int k=t[i].to[j];if(k&&t[i].sz==t[k].sz)nxt[i]=k,vs[k]=1;}}for(int i=1;i<=tot;i++){if(vs[i]==0){cnt=0;int e=0;for(int j=i;j;j=nxt[j])e=j,st[++cnt]=t[j].len-t[t[j].link].len;for(int j=1;j<=cnt;j++)s[j]=s[j-1]+st[j];int p=1,len=t[e].len;for(int j=len-cnt+1;j<=st[cnt]&&j<=len+1;j++){while(p<=cnt&&st[p]<j)p++;res+=s[cnt-len+j-1]*(cnt-p+1);}}}cout<<res;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/91334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RabbitMQ实战】 03 SpringBoot RabbitMQ生产者和消费者示例

上一节我们写了一段原生API来进行生产和消费的例子。实际上SpringBoot对原生RabbitMQ客户端做了二次封装&#xff0c;让我们使用API的代价更低。 一、配置文件 依赖引入 <dependencies><dependency><groupId>org.springframework.boot</groupId><…

2023年十大开源项目:革新技术创新

来源整理 : 小托 | 开源社翻译组PM 翻译 : 张锋 | 开源社翻译 Open-source projects have revolutionized the world of software development by fostering innovation, collaboration, and community-driven contributions. These projects are often the backbone of countl…

PHP8的继承和多态-PHP8知识详解

我们在前面的时候讲过《面向对象编程的特点》时&#xff0c;面向对象编程具有3大特点&#xff1a;封装性、继承性和多态性。 继承和多态的根本作用就是完成代码的重用。下面就来讲解php8的继承和多态。 1继承 子类可以继承父类的所有成员变量和成员方法&#xff0c;包括构造方…

玄子Share 设计模式 GOF 全23种 + 七大设计原则

玄子Share 设计模式 GOF 全23种 七大设计原则 前言&#xff1a; 此文主要内容为 面向对象七大设计原则&#xff08;OOD Principle&#xff09;GOF&#xff08;Gang Of Four&#xff09;23种设计模式拓展的两个设计模式 简单工厂模式&#xff08;Simple Factory Pattern&#x…

小白入门pytorch(二)----神经网络

本文为&#x1f517;[小白入门Pytorch]学习记录博客 文章目录 前言一、神经网络的组成部分1.神经元2.神经网络层3.损失函数4.优化器 二、Pytorch构建神经网络中的网络层全连接层2.卷积层3.池化层4.循环神经网络5.转置卷积层6.归一化层7.激活函数层 三、数据加载与预处理1.数据加…

【计算机网络】 TCP和UDP的区别

文章目录 区别相关问题 区别 UDP是无连接的&#xff0c;TCP面向连接。UDP是不可靠传输&#xff0c;不使用流量控制和拥塞控制。而TCP是可靠传输&#xff0c;使用流量控制和拥塞控制。UDP支持一对一&#xff0c;一对多&#xff0c;多对一和多对多交互通信&#xff0c;而TCP只能…

uvm白皮书练习_ch2_ch223_加入objection机制

UVM中通过objection机制来控制验证平台的关闭。 在每个phase中&#xff0c;UVM会检查是否有objection被提起&#xff08;raise_ objection&#xff09;&#xff0c;如果有&#xff0c;那么等待这个objection被撤销&#xff08;drop_objection&#xff09;后停止仿真&#xff1b…

Fake Maxpooling 二维滑动窗口

先对每一行求一遍滑动窗口&#xff0c;列数变为(列数-k1) 再对每一列求一遍滑动窗口&#xff0c;行数变为(行数-k1) 剩下的就是每一个窗口里的最大值啦 #include<bits/stdc.h> #define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl \nusing nam…

关于Greenplum为什么基于PostgreSQL而不是MySQL?

Greenplum选择PostgreSQL而不是MySQL&#xff0c;其原因主要有以下几点&#xff1a; 更强的分析能力 PG有非常强大的SQL支持能力和非常丰富的统计函数和统计语法支持&#xff0c;除对ANSI SQL完全支持外&#xff0c;还支持比如分析函数&#xff08;SQL2003 OLAP window函数&a…

【强化学习】基础概念

1. Agent (智能体) 智能体是进行决策和学习的实体&#xff0c;它能感知环境的状态&#xff0c;并基于策略采取动作以影响环境。智能体的目标是通过与环境的交互获得最大化的累积奖励。 2. Environment (环境) 环境是智能体所处的外部系统&#xff0c;它与智能体交互。环境的…

【算法】莫队

这篇博客起源于本人把一道 p o w ( 2 , n ) pow(2,n) pow(2,n) 的问题考虑成求组合数前缀和的问题qwq&#xff0c;于是接触到了这个新算法来总结一下 参考自这篇文章&#xff0c;写得太好了 首先是一道模板题 题目意思是&#xff0c;给出一个数组a&#xff0c;再给出多个区…

无人直播间

失败&#xff01;&#xff01; 采用 ffmpeg 技术进行推流 推流代码&#xff1a; 【需要将rtmp替换为你的推流地址】 ffmpeg -re -stream_loop -1 -i "rain.mp4" -c copy -f flv ""推流地址获取 以哔哩哔哩为例 点击下方链接 开播设置 - 个人中心 - …

leetcode之打家劫舍

leetcode 198 打家劫舍 leetcode 213 打家劫舍 II leetcode 337. 打家劫舍 III 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 &#xff0c;这意味着第一个房屋和最后一个房屋是紧挨着的。同时&#…

【MATLAB源码-第39期】基于m序列/gold序列的直接扩频通信仿真,编码方式采用卷积码,调制方式采用BPSK。

1、算法描述 直接序列扩频通信系统的仿真一般包括以下几个主要步骤&#xff1a;信号产生、扩频、卷积编码、BPSK调制、信道传输、BPSK解调、卷积码译码和解扩。 信号产生&#xff1a; 首先&#xff0c;产生一个二进制数据序列作为待发送的信息位。 扩频&#xff1a; 采用m序列…

React Promise 中断

需求&#xff1a; 上传文件&#xff0c;但是后端接口不支持多文件上传&#xff0c;但是一次性发出很多请求的话如果有100个文件那对后端的压力又太大了在上传的时候还需要有停止上传的按钮 进程&#xff1a; async await 只能做到第一步&#xff0c;但是无法在上传中的时候关…

HBASE集群主节点迁移割接手动操作步骤

HBASE集群主节点迁移割接手动操作步骤 HBASE集群主节点指的是包含zk、nn、HM和rm服务的节点&#xff0c;一般这类服务都是一起复用在同一批节点上&#xff0c;我把这一类节点统称为HBASE集群主节点。 本文中使用了rsync、pssh等工具&#xff0c;这类是开源的&#xff0c;自己…

JVM的主要组成及其作用

jvm主要组成部分有: 类加载器、运行时数据区 (内存结构)、执行引擎、本地接口库、垃圾回收机制 Java程序运行的时候&#xff0c;首先会通过类加载器把Java 代码转换成字节码。然后运行时数据区再将字节码加载到内存中&#xff0c;但字节码文件只是JVM 的一套指令集规范&#xf…

如何开始着手一篇Meta分析 | Meta分析的流程及方法

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;最早出现于“循证医学”&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面。…

十五、异常(3)

本章概要 捕获所有异常 多重捕获栈轨迹重新抛出异常精准的重新抛出异常异常链 捕获所有异常 可以只写一个异常处理程序来捕获所有类型的异常。通过捕获异常类型的基类 Exception&#xff0c;就可以做到这一点&#xff08;事实上还有其他的基类&#xff0c;但 Exception 是所…

鸿鹄工程项目管理系统 Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统

项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管理的提升提出了更高的要求。 二、企业通过数字化转型&#xff0c;不仅有利于优化业务流程、提升经营管理…