LOJ2823 three friends - the hash value of the query string

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

 

Guess you like

Origin www.cnblogs.com/lfri/p/11375342.html