HDU 4821 String 字符串hash(水

题意:

给定整数M L

一个字符串s

我们定义一个子串为"好"串 iff

1、长度为 M*L

2、把这个好串分成M段,每段长度为L,且每段各不相同。

且我们得到的这些好串不重复计算(即把这些好串去重)

问有几个好串

#include <stdio.h>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
typedef unsigned long long ull;
const int N = 100005;
int n, m;
char s[N];
ull base[N], has[N], bas = 31;
map<ull, int>mp;
int main(){
    base[0] = 1;
    for(int i = 1; i < N; i++)base[i] = base[i-1]*bas;

    while(cin>>n>>m){
        scanf("%s", s);
        int slen = strlen(s);
        has[slen] = 0;
        for(int i = slen-1; i >= 0; i--)
            has[i] = has[i+1]*bas+s[i]-'a'+1;
        int ans = 0;
        for(int i = 0; i < m && i+n*m<=slen; i++)
        {
            mp.clear();
            for(int j = i; j < i+n*m; j+=m)
            {
            	mp[ has[j] - has[j+m]*base[m] ] ++;
            }
            ans += mp.size() == n;
            for(int j = i+n*m; j+m <= slen; j+=m){
            	ull tmp = has[j-n*m] - has[j-(n-1)*m]*base[m];
            	mp[tmp] --;
            	if(mp[tmp]==0)mp.erase(tmp);
            	tmp = has[j] - has[j+m]*base[m];
            	mp[tmp]++;
            	ans += mp.size() == n;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
时间: 2024-10-12 13:05:39

HDU 4821 String 字符串hash(水的相关文章

hdu 4821 String(字符串hash)

题目链接:hdu 4821 String 题意: 给你一个字符串,问你有多少子串,满足长度为m*len,并且这个子串能分成m个len长度的不同串. 题解: BKDRhash+map来判重.注意的是要以len长分类来扫,这样才不会超时. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 typedef unsigned long long ull; 5 co

HDU 4821 String (HASH)

题意:给你一串字符串s,再给你两个数字m l,问你s中可以分出多少个长度为m*l的子串,并且子串分成m个长度为l的串每个都不完全相同 首先使用BKDRHash方法把每个长度为l的子串预处理成一个数字,接着根据题意直接map判重 BKDRHash:一种常用字符串hash,hash简单来说就是把一串字符串通过一些转化成为一个数字,并保证相同字符串转化的数字一样,不相同字符串转化的数字一定不一样.方法就是hash[i]=hash[i-1]*seed(进制)+str[i]-'a'+1(注意要加一,因为不

[HDU 4821] String (字符串哈希)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 题目大意:给你M,L两个字母,问你给定字串里不含M个长度为L的两两相同的子串有多少个? 哈希+枚举 我就是不会枚举这样的,这次涨姿势了. 每次枚举起点,然后就能枚举全部的. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #inclu

[字符串hash] hdu 4821 String

题意: 给你M,L,再给一个串str 任意截取M*L长度的连续子串 再把这个子串分成M份长度为L的连续串 使得这M份互不相同 问有几种截取方法 思路: 考虑到子串是否相等,就运用字符串hash 用到map判重和割补的办法优化 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #in

hdu4821 String 字符串hash(bkdrhash)

题意:给定m,l,一个字符串str. 我们定义一个子串为"recoverable"串 当 1.长度为 M*L 2.把这个好串分成M段,每段长度为L,且每段各不相同. 求"recoverable"串的个数,串相同位置不同也算不同. 思路:预处理数组hash,hash[i]表示从i位置到尾的字符串hash值.这里数组为unsigned long long型,因为可以自动取模.然后枚举 前l个位置,每次向后翻滚(将前一个长度为l的段hash值从map中去除,将翻滚后新出现

HDU 4821 String

String 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 题目大意: 给定一个字符串(最长10^5).从中选一个长度为 m * l 的子串,要求该子串能拆分为m个长度为 l 的一一不同的串.问有多少种取法. 解题思路: 比赛的时候,没有将串按照模 l 之后分类,导致TLE.. 字符串的哈希为:a[i] = a[i+1] * seek + str[i] - 'a' + 1; 那么j到j+len之间的字符串的哈希值是:a[j] - a[j+

杭电oj1860:统计字符(字符串hash / 水题)

统计字符 题目链接 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 统计一个给定字符串中指定的字符出现的次数 Input 测试输入包含若干测试用例,每个测试用例包含2行,第1行为一个长度不超过5的字符串,第2行为一个长度不超过80的字符串.注意这里的字符串包含空格,即空格也可能是要求被统计的字符之一.当读到'#'时输入结束,相应的结果不要输出.

HDU 2094 产生冠军 hash 水题

Problem Description 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛.球赛的规则如下:如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C.如果A打败了B,B又打败了C,而且,C又打败了A,那么A.B.C三者都不可能成为冠军.根据这个规则,无需循环较量,或许就能确定冠军.你的任务就是面对一群比赛选手,在经过了若干场撕杀之后,确定是否已经实际上产生了冠军. Input 输入含有一些选手群,每群选手都以一个整数n(n<1000)开头

hdu 4821 字符串hash+map判重 String (长春市赛区I题)

http://acm.hdu.edu.cn/showproblem.php?pid=4821 昨晚卡了非常久,開始TLE,然后优化了之后,由于几个地方变量写混.一直狂WA.搞得我昨晚都失眠了,,. 这几次hash军写错的变量--tmp=(j==m-1)?ah[j]:(ah[j]-ah[j-m]*base[m]);  外层循环变量是i,我写的字符串hash的几题都写成tmp=(i==0)? ah[j]:(ah[j]-ah[j-m]*base[m]); 二逼啊 题目大意: 给定一个字符串(最长10^