2024牛客五一集训派对day1 C. Gifted Composer 【二分Hash、循环节】

C. Gifted Composer

传送门

题意

一个字符串初始为空,每次操作可以在其开头末尾添加一个字符,对每次操作后的字符串,询问有多少个不同的循环节长度

思路

首先,对于循环节的判断,我们可以用哈希,有这样一个判定方法:

如果一个长度为 n n n 的字符串 s s s 有某个循环节长度 x x x,那么意味着: ∀ i > x , s i = s i − x \forall i > x, s_i = s_{i - x} i>x,si=six
因此等价于: h a s h [ 1 , n − x ] = h a s h [ 1 + x , n ] hash[1, n - x] = hash[1 + x, n] hash[1,nx]=hash[1+x,n],也就是 [ 1 , n − x ] [1, n - x] [1,nx] 的哈希值与 [ 1 + x , n ] [1 + x, n] [1+x,n] 相等

同时,对于某个循环节长度 x x x,我们不难注意到它是满足二分单调性的,具体如下:

  • 如果一个长度为 l e n len len 的字符串拥有循环节长度 x x x,那么在它的开头和末尾删除若干个字符,只要最终长度大于等于 x x x,它还是拥有循环节长度 x x x
  • 如果某个长度大于等于 x x x 的字符串没有循环节长度 x x x,那么在它的末尾或开头添加若干个字符,永远也不会拥有循环节长度 x x x,这是因为在初始的 s s s 中已经有某个位置 s i ≠ s i − x s_i \neq s_{i - x} si=six,造成了污染

因此我们可以考虑对于每个循环节长度 x x x,我们通过二分来判断它最后出现的位置
预处理出最终字符串的 h a s h hash hash 数组,并记录每次操作后的头尾指针,然后利用差分计数即可

时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn)

#include<bits/stdc++.h>
#define fore(i,l,r)	for(int i=(int)(l);i<(int)(r);++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()
#define Debug(x, ed) std::cerr << #x << " = " << x << ed;const int INF=0x3f3f3f3f;
const long long INFLL=1e18;typedef long long ll;const int N = 1000050;std::pair<int, int> p[N]; //每次操作完后的头尾下标
ull s[3 * N];
ull hash[3 * N];
ull P[N]; //进制的幂inline ull f(std::string& c){if(c == "do") return 1;if(c == "re") return 2;if(c == "mi") return 3;if(c == "fa") return 4;if(c == "sol") return 5;if(c == "la") return 6;return 7;
}void init(int n){auto [l, r] = p[n];const ull p = 1313;ull h = 0;P[0] = 1;int cnt = 0;fore(i, l, r + 1){hash[i] = hash[i - 1] * p + s[i];++cnt;P[cnt] = P[cnt - 1] * p;} 
}ull get_hash(int l, int r){return hash[r] - hash[l - 1] * P[r - l + 1];
}int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int n;std::cin >> n;int head = N, tail = N - 1;fore(i, 1, n + 1){char opt;std::string c;std::cin >> opt >> c;if(opt == 'a')  s[++tail] = f(c);else    s[--head] = f(c);p[i] = {head, tail};}init(n);std::vector<int> ans(n + 5, 0); //差分数组ans[n] = 1;fore(x, 1, n){int e = x;int l = x + 1, r = n;while(l <= r){int mid = l + r >> 1;auto [head, tail] = p[mid]; //mid步的左右端点ull v1 = get_hash(head, tail - x), v2 = get_hash(head + x, tail);if(v1 == v2){e = mid;l = mid + 1;}else r = mid - 1;}++ans[x];--ans[e + 1];}fore(i, 1, n + 1){ans[i] += ans[i - 1];std::cout << ans[i] << endl;}return 0;
}

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

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

相关文章

深度学习实战76-基于目标检测YOLOv5模型的迁移学习使用方法,YOLOv5的原理与结构

大家好,我是微学AI,今天给大家介绍一下深度学习实战76-基于目标检测YOLOv5模型的迁移学习使用方法,YOLOv5的原理与结构。YOLOv5(You Only Look Once version 5)是一种先进的目标检测算法,基于深度学习的单阶段目标检测模型。它的主要原理是通过一次前向传播就同时预测图像…

Redis是什么? 日常运维 Redis 需要注意什么 ? 怎么降低Redis 内存使用 节省内存?

你的项目或许已经使用 Redis 很长时间了&#xff0c;但在使用过程中&#xff0c;你可能还会或多或少地遇到以下问题&#xff1a; 我的 Redis 内存为什么增长这么快&#xff1f;为什么我的 Redis 操作延迟变大了&#xff1f;如何降低 Redis 故障发生的频率&#xff1f;日常运维…

c++ priority_queue用法

1 priority_queue的定义 基本定义方法&#xff1a; 基本定义默认是使用大顶堆的&#xff0c;即队首总是最大的元素 priority_queue<int> q;//储存int型数据 priority_queue<double> q;//储存double型数据 priority_queue<string> q;//储存string型数据 …

英语学习笔记1——Excuse me!

Excuse me! 对不起&#xff01; 词汇 Vocabulary excuse v. 原谅 [iks’kju:z] 用法&#xff1a;1. Excuse me! 对不起&#xff01; 用于以下场景&#xff1a; 向陌生人问路 牢记引起别人注意中途离开某个场所。发出怪声&#xff08;如打喷嚏之后&#xff09; 和 I’m sorr…

详解AI作画算法原理

AI作画算法的原理通常涉及深度学习和计算机视觉技术。下面是一个简要的解释&#xff1a; 数据准备&#xff1a;首先&#xff0c;需要准备大量的绘画数据&#xff0c;包括各种风格和类型的绘画作品。这些数据通常由艺术家的作品组成&#xff0c;可以包括油画、水彩画、素描等。 …

【C++】 constexpr 关键字的使用和示例

constexpr是C中一个重要的关键字&#xff0c;它用于声明可以在编译时期计算的变量和函数。这意味着使用constexpr声明的实体可以在编译时求值&#xff0c;从而可以作为模板参数或数组大小等需要编译时确定的上下文中使用 1. 定义变量 constexpr变量必须在定义时初始化&#x…

【代码随想录算法训练营第37期 第一天 | LeetCode704. 二分查找、27. 移除元素】

代码随想录算法训练营第37期 第一天 | LeetCode704. 二分查找、27. 移除元素 一、704. 二分查找 解题代码C&#xff1a; class Solution { public:int search(vector<int>& nums, int target) {int len nums.size();int l 0, r len - 1;while(l < r){int mid…

大数据与会计专业主要学什么课程

大数据与会计专业是一个结合了传统会计知识与现代大数据技术的交叉学科&#xff0c;旨在培养既懂会计又熟悉大数据分析的复合型人才。该专业的学生将会学习以下主要课程内容&#xff1a; 会计基础课程&#xff1a;包括基础会计、财务会计、成本会计、管理会计等&#xff0c;这些…

有了这么多套件,为什么还需要APaaS

文/明道云创始人任向晖 在明道云的业务活动中&#xff0c;比较常见的一个问题是和套件应用的关系。一个有具体应用需求的客户为什么不从市场上购买现成的套件应用&#xff0c;而要选择APaaS来构建呢&#xff1f;反过来说似乎也成立&#xff0c;既然一个平台什么应用都能搭建&a…

使用双指针解决问题题集(二)

1. 有效三角形的个数 给定一个包含非负整数的数组 nums &#xff0c;返回其中可以组成三角形三条边的三元组个数。 示例 1: 输入: nums [2,2,3,4] 输出: 3 解释:有效的组合是: 2,3,4 (使用第一个 2) 2,3,4 (使用第二个 2) 2,2,3 示例 2: 输入: nums [4,2,3,4] 输出: 4 题解&a…

软件系统测试方案书(测试计划-Word原件)

2 引言 2.1 编写目的 2.3 测试人员 2.4 项目背景 2.5 测试目标 2.6 简写和缩略词 2.7 参考资料 2.8 测试提交文档 2.9 测试进度 3 测试环境 3.1 软硬件环境 4 测试工具 5 测试策略 5.1 测试阶段划分及内容 5.1.1 集成测试 5.1.2 系统测试 5.1.2.1 功能测试 5.…

深入解析智能指针:从实践到原理

&#x1f466;个人主页&#xff1a;晚风相伴 &#x1f440;如果觉得内容对你有所帮助的话&#xff0c;还请一键三连&#xff08;点赞、关注、收藏&#xff09;哦 如果内容有错或者不足的话&#xff0c;还望你能指出。 目录 智能指针的引入 内存泄漏 RAII 智能指针的使用及原…

STM32F10x移植FreeRTOS

一、获取FreeRTOS源码 &#xff08;1&#xff09;登录FreeRTOS官网&#xff1a;www.freertos.org&#xff0c;下载第一个压缩包 &#xff08;2&#xff09;通过GitHub网站&#xff1a;github.com/FreeRTOS/FreeRTOS下载&#xff0c;由于该网站服务器在国外&#xff0c;所以访问…

1688快速获取整店铺列表 采集接口php Python

在电子商务的浪潮中&#xff0c;1688平台作为中国领先的批发交易平台&#xff0c;为广大商家提供了一个展示和销售商品的广阔舞台&#xff1b;然而&#xff0c;要在众多店铺中脱颖而出&#xff0c;快速获取商品列表并进行有效营销是关键。 竞争对手分析 价格比较&#xff1a;…

【强训笔记】day12

NO.1 思路&#xff1a;哈希表&#xff0c;建立bool数组&#xff0c;将要删除的字符串存入哈希表&#xff0c;并标为true&#xff0c;再遍历要做处理的字符串&#xff0c;如果在哈希表中为false&#xff0c;就输出。 代码实现&#xff1a; #include <iostream> #includ…

喜报 | 擎创科技荣获NIISA联盟2023年度创新技术特等奖!

为深入实施创新驱动发展战略&#xff0c;紧紧把握全球科技革命和产业变革方向&#xff0c;密切跟踪前沿科技新趋势&#xff0c;经科技部中国民营促进会业务主管部门批准以及国家互联网数据中心产业技术创新战略联盟&#xff08;以下简称联盟&#xff09;总体工作安排&#xff0…

代码随想录算法训练营第十八天:二叉树的层序遍历(中间放假)

代码随想录算法训练营第十八天&#xff1a;二叉树的层序遍历&#xff08;中间放假&#xff09; ‍ ​​ 102.二叉树的层序遍历 力扣题目链接(opens new window) 给你一个二叉树&#xff0c;请你返回其按 层序遍历 得到的节点值。 &#xff08;即逐层地&#xff0c;从左到右…

Java 框架安全:Struts2 漏洞序列测试.

什么是 Struts2 框架 Struts 2 是一个用于创建企业级 Java 应用程序的开源框架。它是一个 MVC&#xff08;模型-视图-控制器&#xff09;框架&#xff0c;用于开发基于 Java EE&#xff08;Java Platform, Enterprise Edition&#xff09;的 Web 应用程序。Struts 2 主要解决…

【Linux】HTTPS

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;Linux 目录 &#x1f449;&#x1f3fb;HTTPS协议概念&#x1f449;&#x1f3fb;加密为什么要进行加密 &#x1f449;&#x1f3fb;常见的加密方式对称加密…

【MATLAB源码-第204期】基于matlab的语音降噪算法对比仿真,谱减法、维纳滤波法、自适应滤波法;参数可调。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 语音降噪技术的目的是改善语音信号的质量&#xff0c;通过减少或消除背景噪声&#xff0c;使得语音更清晰&#xff0c;便于听者理解或进一步的语音处理任务&#xff0c;如语音识别和语音通讯。在许多实际应用中&#xff0c;如…