【來源】:bzoj3916html
【參考博客】ide
【題解】post
首先hash整個串,而後分紅三種狀況,分別是前半段,中間,後半段,三段的字母試圖去掉看可否拼起來。url
若是能夠,那麼還須要考慮是否爲惟一的。spa
惟一的意思是: 串S,若是有選擇兩個不一樣的串S也能構成這個原串。.net
代碼仍是參考別人寫的。code
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 // NOT POSSIBLE = Odd or Not found a S 16 // NOT UNIQUE = exist least two S 17 // Else = The answer S 18 19 // 切割字符串返回hash值 20 ull Cut_str( int L ,int R ){ 21 ull ans = Hash[R] - Hash[L-1] * Pow[R-L+1] ; 22 return ans ; 23 } 24 25 bool check (int i){ 26 //若是未被標記過,則標記 返回true 27 //若是標記過,同時這個字符串和暫存的串不同則返回false 28 if( pos == -1 || S == Lstr ){ 29 pos = i ; 30 S = Lstr ; 31 return true ; 32 }else{ 33 return false ; 34 } 35 } 36 int main() 37 { 38 scanf("%d%s",&n,str+1); 39 Mid = n >> 1 ; 40 41 //偶數狀況下沒法構成 42 if( n%2==0 ) return puts("NOT POSSIBLE"),0; 43 44 Pow[0] = 1; 45 for(int i=1;i<=n;i++){ 46 Pow[i] = Pow[i-1] * base ; 47 Hash[i] = Hash[i-1] * base + (ull)(str[i]-'A'+1); 48 //全部字符串只包含大寫英文字母 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 */