BZOJ 3916: [Baltic2014]friends


BZOJ 3916: [Baltic2014]friends 

Description

有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将其复制一遍得到T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在你得到了U,请你找出S.

Input

第一行一个数N,表示U的长度.
第二行一个字符串U,保证U由大写字母组成

Output

输出一行,若S不存在,输出"NOT POSSIBLE".若S不唯一,输出"NOT UNIQUE".否则输出S.

Sample Input

Sample Input1:
7
ABXCABC


Sample Input2:

6
ABCDEF

Sample Input3:

9
ABABABABA

Sample Output

Sample Output1:

ABC

Sample Output2:

NOT POSSIBLE

Sample Output3:

NOT UNIQUE

HINT

对于100%的数据 2<=N<=2000001

思路 :

  对整个字符串进行hash,枚举插入字符位置,分三种情况讨论:在前半段, 在中间,在后半段, 分别把枚举到的剔除,把两段hash接到一起,与另外半串对比 若hash相同则存下来,等到下一次出现相同的时候判断是否重复,重复输出NOT UNIQUE ,如果一直没有ans 输出NOT POSSIBLE 如果所有答案的hash是相同的,在出答案的时候记录插入字符的位置,直接输出另外半段字符串即可 代码如下

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char s[2100001];
unsigned int h1[2100001],mi[2100001];
unsigned int hav[2100001],tot;
const int p = 1313131;
int idx,n;
unsigned int creat(int l,int r) {
    if(l>r)return 0;
    return h1[r]-h1[l-1]*mi[r-l+1];
}
bool check(int x) {
    if(x<=idx) {
        unsigned int x1 = creat(1,x-1);
        unsigned int x2 = creat(x+1,idx+1);
        unsigned int x3 = creat(idx+2,n);
        (x1*=mi[idx-x+1])+=x2;
        if(x1==x3){hav[++tot]=x1;return 1;}
    }
    else if(x==idx+1)  {
        unsigned int x1 = creat(1,x-1);
        unsigned int x3 = creat(x+1,n);
        if(x1==x3) 
        {hav[++tot]=x1;return 1;}
    }
    else {
        unsigned int x1 = creat(1,idx);
        unsigned int x2 = creat(idx+1,x-1);
        unsigned int x3 = creat(x+1,n);
        (x2*=mi[n-x])+=x3;
        if(x2==x1) {hav[++tot]=x1;return 1;}
    }
    return 0;
}
void print(int x) {
    if(x==1) {
        for(int i=1;i<=n/2;i++) {
            putchar(s[i]);
        }
    }
    else {
        for(int i=n/2+2;i<=n;i++) {
            putchar(s[i]);
        }
    }
}
int main() {
   // freopen("2.in","r",stdin);
    scanf("%d%s",&n,s+1);
    idx=(n-1)/2;
    /*puts("NOT UNIQUE");
    return 0;*/
    if(!(n&1)) {
        puts("NOT POSSIBLE");
        return 0;
    }
    mi[0]=1;
    int i,cnt=0;
    for(i=1;i<=n;i++) {
        mi[i]=mi[i-1]*p;
        h1[i]=h1[i-1]*p+s[i];
    }
    /*for(i=1;i<=n;i++) {
        if(h1[i])printf("%d\n",i);
    }*/
    int tmp=0;
    for(i=1;i<=n;i++) {
        if(check(i)) 
        {
            //printf("%d\n",i);
            cnt++,tmp=i;
        }
			
    }
    sort(hav+1,hav+tot+1);
    int amt=0;
    for(i=1;i<=tot;i++) {
        if(hav[i]!=hav[i-1])amt++;
    }
    if(cnt>1&&amt>1) {
        puts("NOT UNIQUE");
    }
    else if(!cnt) {
        puts("NOT POSSIBLE");
    }
    else {
        if(tmp<=idx+1) {
            print(2);
        }
        else {
            print(1);
        }
    }
}

 欢迎来原博客看看 >原文链接<

posted @ 2018-05-23 20:14  TOBICHI_ORIGAMI  阅读(302)  评论(0编辑  收藏  举报