A Horrible Poem-字符串哈希+线性筛

2024-02-12 09:40

本文主要是介绍A Horrible Poem-字符串哈希+线性筛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

A Horrible Poem-字符串哈希+线性筛

题目描述

题目描述

题解

首先明确几个性质
1,循环节的长度必为该区间 S [ a . . . b ] S[a...b] S[a...b]长度的约数—显而易见
2,当 S [ a . . . b − l e n ] = = S [ a + l e n . . . b ] S[a...b-len]==S[a+len...b] S[a...blen]==S[a+len...b]时, S [ x . . . y ] S[x...y] S[x...y]必为 S [ a . . . b ] S[a...b] S[a...b]的循环节;( l e n len len S [ x . . . y ] S[x...y] S[x...y]的长度)
证明可以自己手玩,这是我们判断循环节的重要根据
根据这2条性质,算法显而易见,枚举 l l l的约数( l l l S [ a . . . b ] S[a...b] S[a...b]的长度),然后哈希判断是否为循环节,但该题卡 O ( n √ n ) O(n√n) O(nn),因此线性筛横空而出,首先预处理-线性筛,维护出每个数的最小质因数,然后比如找 l l l的质因数时就递归思想,继续找 l / v [ l ] l/v[l] l/v[l]的质因数,( v [ i ] v[i] v[i]表示 i i i的最小质因数)

代码

#include<bits/stdc++.h>//字符串哈希判循环节 
#define M 500009
#define LL unsigned long long
using namespace std;
int n,q,v[M],p[M],t[M],cnt;
LL has[M],mi[M];
char s[M];
const int h=31;
int read(){int f=1,re=0;char ch;for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());if(ch=='-'){ch=getchar();f=-1;}for(;isdigit(ch);ch=getchar()) re=(re<<3)+(re<<1)+ch-'0';return re*f;
}
void init(){for(int i=2;i<=n;i++){if(!v[i]){v[i]=i;p[++cnt]=i;}for(int j=1;j<=cnt;j++){if(p[j]*i>n||v[i]<p[j]) break;v[p[j]*i]=p[j];}}cnt=0;
}
LL gethas(int l,int r){return has[r]-has[l-1]*mi[r-l+1];
}
int main(){n=read(),init();scanf("%s",s+1),mi[0]=1;for(int i=1;i<=n;i++){has[i]=has[i-1]*h+(s[i]-'a');mi[i]=mi[i-1]*h;}q=read();for(int i=1;i<=q;i++){int l=read(),r=read();int len=r-l+1;cnt=0;while(len!=1){t[++cnt]=v[len];len=len/v[len];//依次找len的质因数 }len=r-l+1; for(int j=1;j<=cnt;j++){//逐渐缩小长度 int ans=len/t[j];if(gethas(l,r-ans)==gethas(l+ans,r)) len=ans;}printf("%d\n",len);}return 0;
} 

这篇关于A Horrible Poem-字符串哈希+线性筛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/702299

相关文章

JSON字符串转成java的Map对象详细步骤

《JSON字符串转成java的Map对象详细步骤》:本文主要介绍如何将JSON字符串转换为Java对象的步骤,包括定义Element类、使用Jackson库解析JSON和添加依赖,文中通过代码介绍... 目录步骤 1: 定义 Element 类步骤 2: 使用 Jackson 库解析 jsON步骤 3: 添

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

python修改字符串值的三种方法

《python修改字符串值的三种方法》本文主要介绍了python修改字符串值的三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录第一种方法:第二种方法:第三种方法:在python中,字符串对象是不可变类型,所以我们没办法直接

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

C#中字符串分割的多种方式

《C#中字符串分割的多种方式》在C#编程语言中,字符串处理是日常开发中不可或缺的一部分,字符串分割是处理文本数据时常用的操作,它允许我们将一个长字符串分解成多个子字符串,本文给大家介绍了C#中字符串分... 目录1. 使用 string.Split2. 使用正则表达式 (Regex.Split)3. 使用

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

哈希表的底层实现(1)---C++版

目录 哈希表的基本原理 哈希表的优点 哈希表的缺点 应用场景 闭散列法 开散列法 开放定值法Open Addressing——线性探测的模拟实现 超大重点部分评析 链地址法Separate Chaining——哈希桶的模拟实现 哈希表(Hash Table)是一种数据结构,它通过将键(Key)映射到值(Value)的方式来实现快速的数据存储与查找。哈希表的核心概念是哈希