【 哈希和哈希表】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;
}

猜你喜欢

转载自blog.csdn.net/Du_Mingm/article/details/83545110