看了别人的代码才过的。
http://blog.csdn.net/scut_pein/article/details/19786707
果然抄别人的代码就会一点都不理解,很多细节都没注意到的。自己搞了好多发RE,TLE,WA才过。
就是char最大为127,最小为-128,而字符种类数必然大于这个值(主要是有100个各不相同的分隔符),所以需要用int形数组来保存合并后的串。
vis是用来标记串编号的,所以只要开大于100的空间就够了。。
合并后的串不但有100个长度为1000的串还有100个分隔符,所以空间至少要开100100。
是while(~scanf("%d",&N)&&N)或者while(scanf("%d",&N)==1&&N)而不是while(~scanf("%d",&N))。。。
自己没有想到解决办法,正确解法是将所有串连成一个大长串,并在串与串之间加一个从未出现过的分隔符将他们隔开,别忘了最后补个结束符。然后对这个串跑一遍后缀数组以及最长公共前缀,从而得到height数组。最后二分公共前缀的长度,然后去检查是否有超过一半的串都拥有这个长度的公共前缀。检查的方法就是寻找连续的height数组的区间,使得区间内的height值都大于公共前缀的长度,而且区间内包含的串的种类数(来自同一个串的后缀算一种)大于串的总个数的一半。再讲具体一点就是遍历一遍,维护区间长度以及区间内串的种类数,然后判断下有没有找到就好了。这类似最小值最大的问题,所以理应想到二分。为何可以这么检查呢?因为后缀数组其实就是将一个字符串的所有后缀排序,然后sa[i]就是后缀i的排名。而height[i]是第i名的后缀与第i-1名的后缀的最长公共前缀。第i名与第i-1名的后缀不一定是后缀j与后缀j-1,但是由于排名是相邻的,所以他们的前缀会非常相似。从而易得出连续的hei