BZOJ 2251 2010 beijing Wc Alien Contact

2251: [2010Beijing Wc] Alien Contact

Time Limit: 30 Sec  Memory Limit: 256 MB
Submit: 1045  Solved: 644
[Submit][Status][Discuss]

Description

After watching the movie "Contact", Xiao P was deeply moved and determined to devote himself to the cause of
finding aliens. So he crawled on the roof every night trying to listen to
alien . Although what he heard was only some noise, he still
rewritten the received signal into a string of 0s and 1s according to the high and low levels of these noises, and believed that the alien information was hidden in
it. He believes that the information sent by the aliens must be repeated in the 01 string he received, so
he hopes to find all the substrings of the 01 string he has received with a repeating number greater than 1. But the
signal string he received is too long, so he wants you to write a program to help him.

Input

The first line of the input file is an integer N representing the length of the signal string received by P. 
The second line of the input file contains a 01 string of length N, which represents the signal string received by little P.

Output

Each line of the output file contains the number of occurrences of a substring with an occurrence greater than 1.
The order of the output is in lexicographical order of the corresponding substrings.

Sample Input

7
1010101

Sample Output

3
3
2
2
4
3
3
2
2

HINT

 

  For 100% data, 0 <=  N <=3000 

 

Source

We know that all substrings of a character can be represented by the prefix of the suffix, so we first use that set to get the sa and height out

Then we consider essentially different repeated substrings, we enumerate from rank[1] to rank[n], there are different substrings when starting from sa[i] at least until the end of sa[i]+h[i]+1

Then check to see if there are any repetitions

#include <bits/stdc++.h>
#define ll long long
#define inf 1e9+10
using namespace std;
inline int read(){
	int x=0;int f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
const int MAXN=1e6+10;
int sa[MAXN],h[MAXN],rank[MAXN],n,tmp[MAXN],cnt[MAXN],p[MAXN];
char ch[MAXN];
inline bool equ (int x, int y, int l) {
	return rank[x]==rank[y]&&rank[x+l]==rank[y+l];
}
void build_suffix(){
	for(int i=1;i<=n;i++) {sa[i]=i;rank[i]=ch[i]-'0'+1;}
	for(int i,pos=0,sig=5,l=0;pos<n;sig=pos){
		for(i=n-l+1,pos=0;i<=n;i++) p[++pos]=i;
		for(i=1;i<=n;i++) if(sa[i]>l) p[++pos]=sa[i]-l;	
		for(i=0;i<=sig;i++) cnt[i]=0;
		for(i=1;i<=n;i++) cnt[rank[i]]++;
		for(i=1;i<=sig;i++) cnt[i]+=cnt[i-1];
		for(i=n;i>=1;i--) sa[cnt[rank[p[i]]]--]=p[i];
		for (i = 1, pos = 0; i <= n; i ++) tmp [sa [i]] = equ (sa [i], sa [i-1], l)? pos: ++ pos;
		for(i=1;i<=n;i++) rank[i]=tmp[i];
		l=!l?1:l<<1;
	}
}
void build_height(){	
	for(int i=1,k,j=0;i<=n;i++){
		if(!(k=sa[rank[i]-1])) {j=0;continue;}
		if(j) j--;
		while(ch[k+j]==ch[i+j]) j++;
		h[rank[i]]=j;
	}
}
int main(){
	n=read();
	scanf("%s",ch+1);
	build_suffix();
	build_height();
	for(int i=1;i<=n;i++){
		for(int j=h[i]+1;sa[i]+j-1<=n;j++){
			int r;
			for(r=i+1;r<=n&&h[r]>=j;r++);
			if(r-i>=2) printf("%d\n",r-i);
		}
	}
	return 0;
}
/*
7  
1010101
*/

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325949413&siteId=291194637