[Source]: bzoj3916
Reference [blog]
BZOJ3916: [Baltic2014]friends
[Hash and hash table] Three Friends
【Baltic2014】【BZOJ3916】friends
【answer】
First, the entire hash string, and then divided into three cases, namely, the first half, the middle, second half, trying to remove the three sections of the letters to see whether it together.
If you can, you also need to consider whether it is unique.
The only means: a string S, if there are selected two different string S can constitute the original string.
Code or reference written by someone else.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 const int N = 2e6+10; 7 typedef unsigned long long ull ; 8 const ull base = 13313; 9 10 ull Pow[N],Hash[N]; 11 ull Lstr , Rstr , S; 12 char str[N],Ans[N]; 13 int n,Mid,pos=-1; 14 15 //POSSIBLE = Not Odd or the NOT found S A 16 // the NOT UNIQUE TWO S = Least exist . 17 // Else of The answer S = 18 is . 19 // cutting string return hash value 20 is ULL Cut_str ( int L, int R & lt) { 21 is ULL = the Hash ANS [R & lt] - the Hash [L- . 1 ] * Pow [L-R & lt + . 1 ]; 22 is return ANS; 23 is } 24 25 BOOL Check ( int I) { 26 is // if they are not labeled, the tag returns true 27 // If labeled, while the string and the string is not the same temporary false if 28 IF(POS == - . 1 || S == Lstr) { 29 POS = I; 30 S = Lstr; 31 is return to true ; 32 } the else { 33 is return to false ; 34 is } 35 } 36 int main () 37 [ { 38 is Scanf ( " % D% S " , & n-, + STR . 1 ); 39 Mid = n->> . 1 ; 40 41 is // case where an even number not constituting 42 is IF(N-% 2 == 0 ) return the puts ( " the NOT POSSIBLE " ), 0 ; 43 is 44 is Pow [ 0 ] = . 1 ; 45 for ( int I = . 1 ; I <= n-; I ++ ) { 46 is Pow [I] = POW [I- . 1 ] * Base ; 47 the Hash [I] = the Hash [I- . 1 ] * Base + (ULL) (STR [I] - ' A ' + . 1 ); 48 // all strings that contain only uppercase English letter 49 } 50 51 // delete one character in [1,Mid] 52 for(int i=1 ; i<=Mid ; i++ ){ 53 Lstr = Cut_str(1,i-1) * Pow[Mid+1-i] + Cut_str(i+1,Mid+1); 54 Rstr = Cut_str(Mid+2,n); 55 if( Lstr == Rstr ) if( !check(i) ) return puts("NOT UNIQUE"),0; 56 } 57 58 // delete Mid + 1 59 Lstr = Hash[Mid] ; 60 Rstr = Hash[n] - Hash[Mid+1] * Pow[Mid]; 61 if( Lstr == Rstr ) if( !check(Mid+1) ) return puts("NOT UNIQUE"),0; 62 63 // delete [Mid+2,n] 64 65 for(int i=Mid+2 ; i<=n; i++ ){ 66 Lstr = Hash[Mid]; 67 Rstr = Cut_str(Mid+1,i-1) * Pow[n-i] + Cut_str(i+1,n); 68 if( Lstr == Rstr ) if( !check(i) ) return puts("NOT UNIQUE"),0; 69 } 70 71 if( pos == -1 ){ 72 return puts("NOT POSSIBLE"),0; 73 } 74 75 int len = n/2,cnt = 0 ; 76 for(int i=1; i<=n && len ; i++ ){ 77 if( pos == i ) continue; 78 Ans[cnt++] = str[i] ; 79 len -- ; 80 } 81 Ans[cnt] = '\0'; 82 printf("%s\n",Ans); 83 return 0 ; 84 } 85 86 /* 87 88 7 89 ABXCABC 90 91 */