hdu 4821

题目

这题比较经典,而且也是区域赛的题,研究了好一会。
一开始主要是题目读错了,我还以为是所有位置都不同才叫“多彩的”,结果只是普通的不同……坑了我好久

一开始想的是一个一个字符压入弹出,像deque那样,发现没法做…l个l个不相同很难处理,然后就改成每l个每l个的动,这样好处理多了,注意一些边界情况,就没什么问题了。

#include<cstdio>
#include<algorithm>
#include<list>
#include<cstring>
#include<iostream>
#include<bitset>
#include<map>
#define ull unsigned long long
using namespace std;
unsigned long long p[100005],has[100005];
int m,l,ans,len;
char s[100005];
ull geth(int x,int y)
{
	return has[y]-has[x-1]*p[y-x+1];
}
int main()
{
	ios::sync_with_stdio(false);
	while(cin>>m>>l)
	{
		ans=0;
		memset(has,0,sizeof(has));
		memset(p,0,sizeof(p));
		cin>>s+1;
		len=strlen(s+1);
		p[0]=1;
		for(int i=1;i<=len;i++)
		{
			has[i]=has[i-1]*131+(s[i]-'a'+1);
			p[i]=p[i-1]*131;
		}
		for(int i=1;i<=l&&i+m*l<=len;i++)
		{
			map<unsigned long long,int>mp;
			for(int j=i;j<i+m*l;j+=l)
			{
				ull x=geth(j,j+l-1);
				mp[x]++;
			}
			if(mp.size()==m)ans++;
			for(int j=i+m*l;j+l-1<=len;j+=l)
			{
				ull x=geth(j,j+l-1);
				mp[x]++;
				ull y=geth(j-m*l,j-m*l+l-1);
				mp[y]--;
				if(mp[y]==0)mp.erase(y);
				if(mp.size()==m)ans++;
			}
		}
		cout<<ans<<endl;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_37073764/article/details/107393098