hdu 4821 滑动窗口+字符串哈希
2016-07-08 14:11
344 查看
String
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2509 Accepted Submission(s): 753
Problem Description
Given a string S and two integers L and M, we consider a substring of S as “recoverable” if and only if
(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
For each test case, output the answer in a single line.
Sample Input
3 3
abcabcbcaabc
Sample Output
2
Source
2013 Asia Regional Changchun
Recommend
liuyiding | We have carefully selected several similar problems for you: 5717 5716 5715 5714 5713
Statistic | Submit | Discuss | Note
一个很low的hash方法,但是能过。
一个串中所有字母对应的数字相加然后取模。
比如hash(abc)= (a-'a'+b-'a'+c-'a') %mod;
设长度为n,对于第i个位置结尾 且长度为L的字符串 ,计算出对应的id值,使得不同字符串id值不同。
这个时候需要用hash,我用的是链地址法,vector数组模拟链地址。
外加经典的滑动窗口
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<sstream>
#include<algorithm>
#include<utility>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<iterator>
#include<stack>
using namespace std;
const int INF=1e9+7;
const double eps=1e-7;
const int maxn=100000;
typedef long long ll;
#define cal(x) (x-'a')
char s[maxn+10];
const int mod=10000;
int N,n;
int id[maxn+10];
vector<int >G[maxn+10];
int M,L;
bool same(int x,int y)
{
int i,j;
for( i=x,j=y ;i>=x-L+1 ;i--,j--)
{
if(s[i]!=s[j]) return false;
}
return true;
}
int getid(int x,int p)
{
int k=G[p].size();
if(k==0)
{
G[p].push_back(x);
N++;
return N-1;
}
for(int i=0;i<k;i++)
{
if(same(G[p][i],x))
return id[G[p][i]];
}
G[p].push_back(x);
N++;
return N-1;
}
void pre()
{
for(int i=0;i<mod;i++)
{
G[i].clear();
}
N=0;
int sum=0;
for(int i=1;i<L;i++)
{
sum+=cal(s[i]);
sum=(sum%mod+mod)%mod;
}
for(int i=L;i<=n;i++)
{
sum+=cal(s[i]);
if(i-L>=1) sum-=cal(s[i-L]);
sum=(sum%mod+mod)%mod;
id[i]=getid(i,sum);
}
}
void work()
{
int ans=0;
int rear,front;
for(int st=L;st<2*L;st++)
{
set<int >se;
front=st;
se.insert(id[st]);
int siz=1;
if(siz==M) ans++;
for(rear=st+L;rear<=n;rear+=L)
{
while(se.count(id[rear]) )
{
se.erase(id[front]);
front+=L;
siz--;
}
se.insert(id[rear]);siz++;
if(siz>M)
{
se.erase(id[front]);
siz--;
front+=L;
}
if(siz<M) continue;
ans++;
}
}
printf("%d\n",ans);
}
int main()
{
while(~scanf("%d%d",&M,&L))
{
scanf("%s",s+1);
n=strlen(s+1);
pre();
work();
}
return 0;
}
相关文章推荐
- gson2.7官网下载
- Spring quartz设置定时任务
- App引导页的实现带圆点指示器
- DataContractJsonSerializer .Net Framework3.5处理Json
- ios developer tiny share-20160708
- ios developer tiny share-20160708
- 【源码】StringBuilder和StringBuffer源码深度剖析
- Linux字符驱动中container_of宏的作用
- IOS 屏幕快照
- 如何显示选择input file的图片
- <LeetCode> 题1: A+B求和
- ArcGIS for Android 临时图层绘制文字 汉字不显示问题
- Python的is None 和 == None
- JAVA 类加载器详解
- YARN
- 统计学习方法-----k近邻法
- 海外跨境直播面临的难题及解决方案
- Android canvas.rotate的应用
- 顶点(vertexs) 图元(primitives) 片元(fragments片断) 像素(pixels)
- Vector、Stack源码解析