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
7
ABXCABC
Sample Input2:
6
ABCDEF
Sample Input3:
9
ABABABABA
Sample Output
Sample Output1:
ABC
Sample Output2:
NOT POSSIBLE
Sample Output3:
NOT UNIQUE
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);
}
}
}
欢迎来原博客看看 >原文链接<