HDU 4821 String hash
String
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=95149#problem/I
Description
(i) It is of length M*L;
(ii) It can be constructed by concatenating M “diversified”
substrings of S, where each of these substrings has length L; two
strings are considered as “diversified” if they don’t have the same
character for every position.
Two substrings of S are considered as “different” if they
are cut from different part of S. For example, string "aa" has 3
different substrings "aa", "a" and "a".
Your task is to calculate the number of different “recoverable” substrings of S.
Input
The input contains multiple test cases, proceeding to the End of File.
The first line of each test case has two space-separated integers M and L.
The second ine of each test case has a string S, which consists of only lowercase letters.
The length of S is not larger than 10^5, and 1 ≤ M * L ≤ the length of S.
Output
Sample Input
3 3 abcabcbcaabc
Sample Output
2
HINT
题意
给你一个字符串,让你找到有多少个长度为m*l的子串,由m个长度为l的不同的串构成的
题解:
hash一下之后,就直接暴力找就好了
暴力得用类似滑块一样优化一下就好了
代码:
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
#define maxn 100005
ll h[maxn*];
ll h2[maxn*];
char str[maxn*];
int n,len,k,s1,s3,vis[maxn],sum[maxn];
ll N=;
ll p=;
ll powp[maxn*]; void get_hash()
{
h[]=(ll)str[];
for(int i=;i<n;i++)
{
h[i]=(h[i-]*p+(ll)str[i]);
while(h[i]<)
h[i]+=N;
if(h[i]>=N)
h[i]%=N;
}
powp[]=1LL;
for(int i=;i<n;i++)
{
powp[i]=powp[i-]*p;
while(powp[i]<)
powp[i]+=N;
if(powp[i]>=N)
powp[i]%=N;
}
}
ll gethash(int l,int r)
{
if(!l)
return h[r];
ll ans=h[r]-h[l-]*powp[r-l+];
if(ans<)
ans%=N;
if(ans<)
ans+=N;
if(ans>=N)
ans%=N;
return ans;
} map<ll ,int> H;
int main()
{
int M,L;
while(scanf("%d%d",&M,&L)!=EOF)
{
memset(vis,,sizeof(vis));
memset(sum,,sizeof(sum));
scanf("%s",str);
len = strlen(str);
n = len;
get_hash();
/*
int ans = len-M*L+1;
for(int i=0;i<L;i++)
{
H.clear();
int flag=0;
for(int j=0;i+(j+1)*L<=len;j++)
{
ll pp=gethash(i+j*L,i+(j+1)*L-1);
if(H[pp])
{
vis[i+(H[pp]-1)*L]=1;
vis[i+j*L]=1;
}
H[pp]=j+1;
}
if(vis[i])sum[i]=1;else sum[i]=0;
for(int j=1;i+j*L+L<=len;j++)
{
sum[i+j*L]=sum[i+(j-1)*L];
if(vis[i+j*L])
{
sum[i+j*L]++; }
if(i+M*L<=len&&sum[i+(M-1)*L]!=0) ans--;
for(int j=M;i+j*L+L<=len;j++)
if(sum[i+(j-M)*L]!=sum[i+j*L]) ans--;
}
*/
int ans = ;
for(int i=;i<L;i++)
{
H.clear();
for(int j=;j<M&&i+(j+)*L-<len;j++)
{
//cout<<i+j*L<<" "<<i+(j+1)*L-1<<" 1"<<" "<<gethash(i+j*L,i+(j+1)*L-1)<<endl;
H[gethash(i+j*L,i+(j+)*L-)]++;
}
//cout<<H.size()<<endl;
if(H.size()==M)ans++;
for(int j=M;i+(j+)*L-<len;j++)
{
//cout<<i+j*L<<" "<<i+(j+1)*L-1<<" 2"<<" "<<gethash(i+(j-M)*L,i+(j+1-M)*L-1)<<endl;
H[gethash(i+(j-M)*L,i+(j+-M)*L-)]--;
if(H[gethash(i+(j-M)*L,i+(j+-M)*L-)]==)
H.erase(gethash(i+(j-M)*L,i+(j+-M)*L-));
H[gethash(i+j*L,i+(j+)*L-)]++;
//cout<<H.size()<<endl;
if(H.size()==M)ans++;
}
}
printf("%d\n",ans);
}
}
HDU 4821 String hash的更多相关文章
- hdu 4821 字符串hash+map判重 String (长春市赛区I题)
http://acm.hdu.edu.cn/showproblem.php?pid=4821 昨晚卡了非常久,開始TLE,然后优化了之后,由于几个地方变量写混.一直狂WA.搞得我昨晚都失眠了,,. 这 ...
- HDU 4821 String (HASH)
题意:给你一串字符串s,再给你两个数字m l,问你s中可以分出多少个长度为m*l的子串,并且子串分成m个长度为l的串每个都不完全相同 首先使用BKDRHash方法把每个长度为l的子串预处理成一个数字, ...
- HDU - 4821 String(窗口移动+map去重+hash优化)
String Given a string S and two integers L and M, we consider a substring of S as “recoverable” if a ...
- HDU 4821 String 字符串hash
String Problem Description Given a string S and two integers L and M, we consider a substring of S ...
- 2013 Asia Regional Changchun I 题,HDU(4821),Hash
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4821 解题报告:搞了很久,总算搞出来了,还是参考了一下网上的解法,的确很巧,和上次湘潭的比 ...
- HDU 4821 String(2013长春现场赛I题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 字符串题. 现场使用字符串HASH乱搞的. 枚举开头! #include <stdio.h ...
- HDU 4821 String(BKDRHash)
http://acm.hdu.edu.cn/showproblem.php?pid=4821 题意:给出一个字符串,现在问你可以找出多少个长度为M*L的子串,该子串被分成L个段,并且每个段的字符串都是 ...
- [HDU 4821] String (字符串哈希)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 题目大意:给你M,L两个字母,问你给定字串里不含M个长度为L的两两相同的子串有多少个? 哈希+枚 ...
- HDU 4821 字符串hash
题目大意: 希望找到连续的长为m*l的子串,使得m个l长的子串每一个都不一样,问能找到多少个这样的子串 简单的字符串hash,提前预处理出每一个长度为l的字符串的hash值 #include < ...
随机推荐
- MySql表中key的区别
我们看到Key那一栏,可能会有4种值,即'啥也没有','PRI','UNI','MUL'1. 如果Key是空的, 那么该列值的可以重复, 表示该列没有索引, 或者是一个非唯一的复合索引的非前导列2. ...
- String.IsNullOrEmpty 方法
参数 value:一个String引用 返回值 如果 value 参数为 空引用(在 Visual Basic 中为 Nothing) 或空字符串 (""),则为 true:否则为 ...
- C#中使用visio控件
C#中使用visio控件 2012-08-25 18:14:19| 分类: 技术相关|举报|字号 订阅 其实就是C#访问VISIO的自动化模型,以前做了不少C#和Excle及word 的交互 ...
- Andorid-Fragment生命周期
官网帮助文档链接: http://developer.android.com/guide/components/fragments.html Fragment的生命周期: Fragment与Activ ...
- HDU 5379 Mahjong tree
题意:在一棵有n个节点的树上放编号从1到n的麻将,要求每个点的儿子节点之间的编号连续,每棵子树内的编号连续. 解法:手推一组样例之后就可以得到如下结论然后从根节点一边讨论一边搜就好了. 当一个节点只有 ...
- HDU 5818 Joint Stacks
Joint Stacks Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- Oracle 数据乱码
原文 Oracle 数据乱码 服务器配置环境变量 NLS_LANG:American_america.ZHS16GBK
- IOS GCD
UIButton * btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; [btn setTitle:@&quo ...
- 使用DDMS测试安卓手机APP的性能(android)
安装/配置: 通过另外一个工具也可以测试手机客户端APP的性能,这就是android开发包中的DDMS工具(Dalvik Debug Monitor Service),先来说一下android开发包的 ...
- ARM处理机模式--内部寄存器
处理器模式 用户模式(user)简称usr 快速中断模式(FIQ)简称fiq 外部中断模式(IRQ)简称irq 特权模式(supervisor)简称sve 数据访问终止模式(abort)简称abt 未 ...