concept
hash value of the query string
We are talking about are usually hash binary hash, because it has some very convenient properties, for example, it has the prefix and similar properties.
Suppose a string referred to as a hash value prefix $ h [i] $, of hexadecimal $ base $, then obviously $ h [i] = [i-1] \ times base + s [i] h $.
Note $ p [i] $ is the $ $ I $ $ Base power, then we can $ O (1) $ obtain a hash value of a string.
typedef unsigned long long ull; ull get_hash(int l, int r) { return h[r] - h[l - 1] * p[r - l + 1]; }
Wherein, multiplied by $ p [r-l + 1] $ corresponds to the left $ r-l + 1 $ bit.
Similarly, we can $ O (1) $ obtain the hash value of the string to delete a character.
ull get_s(int l, int r, int x) { return get_hash(l, x - 1) * p[r - x] + get_hash(x + 1, r); }
example
Meaning of the questions: Given a string $ S $, $ S $ string copy first time, get the string $ T $, then insert a character in $ T $ to give a string $ U $. We are now given string $ U $, required to reconstruct the $ S $.
analysis:
Enumeration each position, the remaining two should be the same string, according to what is determined hash value.
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; const ull base = 233; const int maxn = 2000000+10; ull h[maxn], p[maxn]; char s[maxn]; int len; void init() { ll ans = 0; for(int i=0;i<len;i++) { ans = (ans*base) + (ull)s[i]; h[i] = ans; } p[0] = 1; for(int i=1;i<=len;i++) { p[i] = p[i-1]*base; } } inline ll gethash(int l,int r) { return h[r] - h[l-1]*p[r-l+1]; } inline ll del(int l,intR & lt, int X) { IF (X <L || X> R & lt) return GetHash (L, R & lt); return GetHash (L, X- . 1 ) * P [RX] + GetHash (X + . 1 , R & lt); } inline int check ( int x) // legality checking x bit removed { iF (x <= len / 2 && del ( 0 , len . 1 , x) == del ( 0 , len >> . 1 , x) * P [len >> . 1 ] + del ( 0 , len >> . 1 , X)) return . 1 ; the else IF (X> len / 2&&del(0,len-1,x)==del(0,(len>>1)-1,x)*p[len>>1]+del(0,(len>>1)-1,x)) return 1; else return 0; } int main() { scanf("%d",&len); scanf("%s",s); init(); int cnt = 0; int ii = -1; LL NUM; for ( int I = 0 ; I <len; I ++ ) { IF (Check (I)) { CNT ++ ; IF (II == - . 1 ) { II = I; NUM = del ( 0 , len - . 1 , I); } the else { IF (del ( 0 , len . 1 , II) del == ( 0 , len . 1 , I)) // may be the same string cnt--; } } if(cnt==2) { printf("NOT UNIQUE\n"); return 0; } } if(cnt==1) { int m = 0; for(int j=0;j<len;j++) //输出结果 { if(j==ii) continue; printf("%c",s[j]); m++; if(m==(len-1)/2) break; } printf("\n"); } if(cnt==0) { printf("NOT POSSIBLE\n"); } return 0; }
Reference Links: https://loj.ac/submission/576434