【 雜湊和雜湊表】Three Friends
問題 E: 【 雜湊和雜湊表】Three Friends
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 30 解決: 4
[提交] [狀態] [討論版] [命題人:admin]
題目描述
Three friends like to play the following game. The first friend chooses a string S. Then the second friend constructs a new string T that consists of two copies of the string S. finally, the third friend inserts one letter at the beginning, the end or somewhere inside the string T, thereby creating a string U.
You are given the string U and your task is to reconstruct the original string S.
輸入
The first line of the input contains N(2 ≤ N ≤ 2000001), the length of the final string U. The string U itself is given on the second line. It consists of N uppercase English letters (A, B, C, . . . , Z).
輸出
Your program should print the original string S. However, there are two exceptions:
1.If the final string U could not have been created using the above procedure, you should print NOT POSSIBLE.
2.If the original string S is not unique, you should print NOT UNIQUE.
樣例輸入
7 ABXCABC
樣例輸出
ABC
第一個人選一個串s,第二個人將s複製,得到一個ss串,第三個人在串的任意位置加一個字元得到最終串u
現在給你u,讓你求原始串s,如果有多個原始串s,輸出NOT UNIQUE,如果求不出,輸出NOT POSSIBLE
看樣例,
第一個人選了ABC,第二個人變成ABCABC,第三個人在第一個B後面加個X
字串hash,題目並不難,可我卻讀錯了題,不唯一指的是多個不同的原式串s,而不是多種情況
例如aaa,則應該輸出a,因為雖然有三種方式得到原始串s,但是原始串s是唯一的
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ull; typedef pair<ull,ull> pull; const int maxn = 2e6+7; map<pull,bool> M; const pull p{131LL,13331LL},one{1LL,1LL},zero{0LL,0LL}; pull operator - (pull a,pull b){return make_pair((a.first - b.first),(a.second - b.second));} pull operator * (pull a,pull b){return make_pair((a.first * b.first),(a.second * b.second));} pull operator + (pull a,pull b){return make_pair((a.first + b.first),(a.second + b.second));} pull operator + (pull a,int b){return make_pair((a.first + b ),(a.second + b ));} pull Pow(pull a,int n){ pull ans = one; while(n){ if(n&1)ans = ans*a; a = a*a; n>>=1; } return ans; } pull Strcut(pull *Len,int l,int r){ return r<l?zero:Len[r] - Len[l-1]*Pow(p,r-l+1); } pull Splice(pull a,pull b,int n){ return (n < 0)?a:a*Pow(p,n)+b; } pull crups(pull *Len,int l,int r,int k){ if(k<l || k>r) return Strcut(Len,l,r); return Splice(Strcut(Len,l,k-1),Strcut(Len,k+1,r),r-(k+1) +1); } char a[maxn]; pull Len[maxn]; int main(){ int n; scanf("%d",&n); scanf("%s",a+1); for(int i=1;i<=n;i++) Len[i] = Len[i-1]*p + a[i]; int ansk = -1,flag = 0; for(int k=1;k<=n;k++){ pull x = k< n/2+1?crups(Len,1,n/2+1,k):crups(Len,1,n/2,k); pull y = k<=n/2+1?crups(Len,n/2+2,n,k):crups(Len,n/2+1,n,k); if(x == y){ if(ansk != -1){ if(!M.count(x)) flag = 1; } ansk = k; M[x] = 1; } } if(ansk == -1) printf("NOT POSSIBLE\n"); else if(flag) printf("NOT UNIQUE\n"); else{ if(ansk<=n/2)for(int i=n/2+2;i<=n ;i++)printf("%c",a[i]); else for(int i=1 ;i<=n/2;i++)printf("%c",a[i]); printf("\n"); } return 0; }