zoukankan      html  css  js  c++  java
  • 【bzoj2795】[Poi2012]A Horrible Poem Hash+分解质因数

    题目描述

    给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节。
    如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到。

    输入

    第一行一个正整数n (n<=500,000),表示S的长度。
    第二行n个小写英文字母,表示字符串S。
    第三行一个正整数q (q<=2,000,000),表示询问个数。
    下面q行每行两个正整数a,b (1<=a<=b<=n),表示询问字符串S[a..b]的最短循环节长度。

    输出

    依次输出q行正整数,第i行的正整数对应第i个询问的答案。

    样例输入

    8
    aaabcabc
    3
    1 3
    3 8
    4 8

    样例输出

    1
    3
    5


    题解

    Hash+分解质因数

    考虑如何求出一个字符串的最短循环节?使用KMP求出next数组,n-next[n]即为最短循环节。

    那么考虑本题,判断一个长度是否为循环节,只需要判断前后字符串是否相等即可,可以使用Hash解决。

    因为循环节长度一定是字符串长度的约数,由于一个数的约数最多只有$2sqrt n$个,因此可以枚举约数然后判断,时间复杂度$O(qsqrt n)$

    考虑优化这个过程:如果$i$是循环节,那么$ki (ki|len)$也一定是循环节。所以我们可以对于串长的每个质因子,求出它在最短循环节中的指数次数。具体实现即对于现有循环节,判断除以质因子后是否还是循环节,如果是则除,不是则不变。

    而分解质因数是可以通过线性筛做到线性预处理$O(log n)$查询的,故总时间复杂度为$O(n+qlog n)$。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 500010
    using namespace std;
    typedef unsigned long long ull;
    ull base[N] , hash[N];
    int lp[N] , prime[N] , tot , np[N];
    char str[N];
    bool judge(int l , int r , int len)
    {
    	return hash[l + len - 1] - hash[l - 1] * base[len] == hash[r] - hash[r - len] * base[len];
    }
    int main()
    {
    	int n , i , j , m , l , r , v , now;
    	scanf("%d%s%d" , &n , str + 1 , &m);
    	for(i = 2 ; i <= n ; i ++ )
    	{
    		if(!np[i]) lp[i] = i , prime[++tot] = i;
    		for(j = 1 ; j <= tot && i * prime[j] <= n ; j ++ )
    		{
    			np[i * prime[j]] = 1 , lp[i * prime[j]] = prime[j];
    			if(i % prime[j] == 0) break;
    		}
    	}
    	base[0] = 1;
    	for(i = 1 ; i <= n ; i ++ ) base[i] = base[i - 1] * 2333 , hash[i] = hash[i - 1] * 2333 + str[i];
    	while(m -- )
    	{
    		scanf("%d%d" , &l , &r) , now = v = r - l + 1;
    		while(v != 1)
    		{
    			if(judge(l , r , r - l + 1 - now / lp[v])) now /= lp[v];
    			v /= lp[v];
    		}
    		printf("%d
    " , now);
    	}
    	return 0;
    }
    

     

  • 相关阅读:
    利用Redis和Flask维护一个通用爬虫代理池
    在scrapy_splash中加载本地Cookies
    Splash对接Scrapy
    Selenium和pymongo的简单复习
    Scrapy框架
    web.xml is missing and <failOnMissingWebXml> is set to true
    深入Mybatis配置文件
    SSH和SSM的比较
    classpath路径指什么
    数据库范式
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/7371460.html
Copyright © 2011-2022 走看看