2619 三个好朋友
有三个好朋友喜欢在一起玩游戏,A君写下一个字符串S,B君将字符串S复制一遍得
到两个S拼接而成的字符串T,C君在T的任意位置(包括首尾)插入一个字符得到U.现在
你得到了U,请你找出S。
比如得到U串为ABABA。
那么S串有可能是AB,T串为ABAB,之后在最后一个位置插入A,得到ABABA。
S串还有可能是BA,T串为BABA,之后在第一个位置插入A,得到ABABA。
输入
第1行:一个数n,表示U的长度。(1<=n<=200000) 第2行:一个字符串U,保证U由大写字母组成。输出
输出一行,若S不存在,输出"NOT POSSIBLE".若S不唯一,输出"NOT UNIQUE".否则输出S。输入样例
7 ABXCABC 5 ABABA 5 ABCAABC 5 AVVAC 5 ABBAB 11 XOJECXPOJEC 11 BNEMNBNEMNN输出样例
ABC NOT UNIQUE NOT POSSIBLE NOT POSSIBLE AB XOJEC BNEMN
思路:
字符串Hash模板题,注意分情况讨论以及不熟悉的Hash计算过程。
代码实现:
#include<iostream>
#include<string.h>
#include<math.h>
#include<set>
#include<map>
#include<stdio.h>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
#define ull unsigned long long
using namespace std;
const int N = 4e5 + 100;
const int M = 4e5 + 100;
char str[N];
int n, ans;
ull tmpl, tmpr, tmp_len;
ull power[N], Hash[N];
set<ull>sc;
ull getHash(int l, int r) {
if (l > r) return 0;
return Hash[r] - Hash[l - 1] * power[r - l + 1];
//*****
}
void init(int n) {
memset(Hash, 0, sizeof(Hash));
memset(power, 0, sizeof(power));
ans = 0;
sc.clear();
power[0] = 1;
for (int i = 1; i <= n; i++) {
Hash[i] = Hash[i - 1] * (ull)131 + (ull)(str[i] - 'A' + 1);
power[i] = power[i - 1] * (ull)131;
}
}
void sol(int n) {
for(int i = 1; i <= n; i++) {
tmp_len = 0;
if (i == 1) {
tmpl = getHash(2, (n - 1) / 2 + 1);
tmpr = getHash((n - 1) / 2 + 2, n);
} else if(i == n) {
tmpl = getHash(1, (n - 1) / 2);
tmpr = getHash((n - 1) / 2 + 1, n - 1);
} else if (i == n / 2 + 1) {
tmpl = getHash(1, i - 1);
tmpr = getHash(i + 1, n);
} else if (i <= n / 2) {
tmp_len = n / 2 + 1 - i;
//*********
tmpl = getHash(1, i - 1) * power[tmp_len] + getHash(i + 1, n / 2 + 1);
tmpr = getHash(n / 2 + 2, n);
} else {
tmp_len = n - i;
tmpl = getHash(1, n / 2);
tmpr = getHash(n / 2 + 1, i - 1) * power[tmp_len] + getHash(i + 1, n);
}
if (tmpl == tmpr) {
sc.insert(tmpl);
ans = i;
}
}
}
void mycout(int n) {
if (sc.size() == 0) {
puts ("NOT POSSIBLE");
} else if (sc.size() > 1) {
puts ("NOT UNIQUE");
} else {
int cnt = 0;
for (int i = 1; i <= n; i++) {
if(ans == i) continue;
printf("%c", str[i]);
cnt ++;
if (cnt == (n - 1) / 2) {
puts("");
break;
}
}
}
}
int main () {
#ifdef MYHOME
freopen("input.txt", "r", stdin);
#endif
while (scanf("%d", & n) != EOF) {
scanf("%s", str + 1);
if (n % 2 == 0) {
puts("NOT POSSIBLE");
continue;
}
init(n);
sol(n);
mycout(n);
}
return 0;
}
THE END;