UPC8173【 哈希和哈希表】Three Friends

【 哈希和哈希表】Three Friends

时间限制: 1 Sec  内存限制: 128 MB
提交: 67  解决: 11
[提交] [状态] [命题人: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


刚开始写字符串哈希,这题卡了好一会儿,我觉得主要是对于哈希的理解吧,做法很好想,枚举每一位假设这个是加入的字符,然后判断剩下的两半字符串是否相等就行,
用字符串哈希之后的哈希数表判断可以O(1)判断。
问题的关键在于如何正确进行两个字符串的拼接。
这里给出规律,如果是拼接在主串中所占范围为1到len的子串a和范围为(len+2)到n的子串b,h[n]-h[len+1]*f[n-len-1]+h[len]*f[n-len]
可以看出来,实际上就是将串a的tmp幂次转到和串b相同,也就是乘上相差的tmp的幂次,然后进行加减。(就这么理解吧暂时)

贴本题AC代码,反复改了好久。这题还有个坑点是注意重复的情况,记得开个map用vis标记一下。

#include<bits/stdc++.h>
using namespace std;
typedef long long unsigned llu;
typedef long long ll;
const int N=2e6+5;
const int mod=1e9+7;
const int tmp=31;
string a;
int n;
unsigned long long  f[N];
unsigned long long  h[N];
ll la;
ll ans[N],k;
map<llu,int>vis;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    f[0]=1;
    for(int i=1; i<=N-1; i++)
        f[i]=f[i-1]*tmp;
    cin>>n;
    cin>>a;
    la=a.size();
    if(la%2==0)
    {
        cout<<"NOT POSSIBLE"<<endl;
        return 0;
    }
    memset(h,0,sizeof h);
    for(int i=1;i<=la;i++)h[i]=h[i-1]*tmp+a[i-1]-'A'+1;
  //  cout<<h[3]<<endl;
    int pos=-1;
    llu len=(la>>1);
    for(int i=1; i<=la; i++)
    {
        llu v1,v2;
        if(i<=len)
        {
            v1=h[i-1]*f[len-i+1]+h[len+1]-h[i]*f[len-i+1];
            v2=h[la]-h[len+1]*f[la-len-1];
        }
        else if(i==len+1)
        {
            v1=h[len];
            v2=h[la]-h[len+1]*f[la-len-1];
        }
        else
        {
            v1=h[len];
            v2=h[la]-h[i]*f[la-i]+(h[i-1]-h[len]*f[i-1-len])*f[la-i];
        }
       // cout<<v1<<" "<<v2<<endl;
        if(v1==v2)
        {
            if(pos!=-1&&!vis[v1])
            {
                cout<<"NOT UNIQUE"<<endl;
                return 0;
            }
            else pos=i,vis[v1]=true;
        }
    }
    if(pos==-1)
    {
        cout<<"NOT POSSIBLE"<<endl;
        return 0;
    }//cout<<pos<<endl;
    for(int i=0; i<n; i++)
    {
        if(i==pos-1)
            continue;
        if(len==0)
            break;
        cout<<a[i];
        len--;
    }
    return 0;
}

  






                                                                                                                                         

猜你喜欢

转载自www.cnblogs.com/liuquanxu/p/11409717.html