[bzoj4236]JOIOJI
来自FallDream的博客,未经允许,请勿转载,谢谢。
JOIOJI桑是JOI君的叔叔。“JOIOJI”这个名字是由“J、O、I”三个字母各两个构成的。
最近,JOIOJI桑有了一个孩子。JOIOJI桑想让自己孩子的名字和自己一样由“J、O、I”三个字母构成,并且想让“J、O、I”三个字母的出现次数恰好相同。
JOIOJI桑家有一份祖传的卷轴,上面写着一首长诗,长度为N,由“J、O、I”三个字母组成。JOIOJIさん想用诗中最长的满足要求的连续子串作为孩子的名字。
现在JOIOJI桑将这首长诗交给了你,请你求出诗中最长的、包含同样数目的“J、O、I”三个字母的连续子串。
n<=2*10^5
就是个哈希qaq
假设三种字母的数量分别是a,b,c
那么数量相同的字串,a-b b-c c-a肯定都相同,拿出来哈希一下就好了。
#include<iostream> #include<cstdio> #include<map> #define MN 200000 #define magic 73 #define magic2 233333333 #define ll long long using namespace std; int X;char ch; inline int read() { X = 0 , ch = getchar(); while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9'){X = X * 10 + ch - '0';ch = getchar();} return X; } int a,b,c,n,ans=0; char st[MN+5]; map<ll,int> mp; void ins(int num) { ll hash=(1LL*(b-a+magic)*magic+(b-c+magic))*magic2+c-a; int t=mp[hash]; if(t) ans=max(ans,num-t+1); else mp[hash]=num+1; } int main() { n=read();scanf("%s",st+1);ins(0); for(int i=1;i<=n;i++) { st[i]=='J'?a++:(st[i]=='O'?b++:c++); ins(i); } printf("%d\n",ans); return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream