ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

friends #2823. 「BalticOI 2014 Day 1」三个朋友

2022-07-07 12:05:10  阅读:130  来源: 互联网

标签:输出 le 样例 哈希 BalticOI 字符串 2014 friends


[BalticOI 2014 Day1] Three Friends

题目描述

有一个字符串 \(S\),对他进行操作:

  1. 将 \(S\) 复制为两份,存在字符串 \(T\) 中
  2. 在 \(T\) 的某一位置上插入一个字符,得到字符串 \(U\)

现在给定 \(U\),求 \(S\)。

输入格式

第一行一个整数 \(N\) 代表 \(U\) 的长度。
第二行 \(N\) 个字符代表字符串 \(U\)。

输出格式

  • 如果不能通过上述的步骤从 \(S\) 推到 \(U\),输出 NOT POSSIBLE
  • 如果从 \(U\) 得到的 \(S\) 不是唯一的,输出 NOT UNIQUE
  • 否则,输出一个字符串 \(S\)。

样例 #1

样例输入 #1

7
ABXCABC

样例输出 #1

ABC

样例 #2

样例输入 #2

6
ABCDEF

样例输出 #2

NOT POSSIBLE

样例 #3

样例输入 #3

9
ABABABABA

样例输出 #3

NOT UNIQUE

提示

数据规模与约定

本题采用捆绑测试。

  • Subtask 1(35 pts):\(N \le 2001\)。
  • Subtask 2(65 pts):无特殊限制。

对于 \(100\%\) 的数据,\(2 \le N \le 2 \times 10^6+1\),保证 \(U\) 中只包含大写字母。

说明

翻译自 BalticOI 2014 Day1 B Three Friends

思路

这题是一体经典的字符串哈希题,我们可以先求出每个字符串得哈希值,但是这题有些字符串有多余字符,因为每一个哈希值都是\(p\)进制数,所以我们可以通过进制转换来消除多余得字符。比如\(abcde\)这么一个字符串有\(c\)这个字符是多余得,那该怎么得到\(abde\)这么一个字符串呢?我们可以先把原字符串以\(c\)分割成\(ab\)和\(de\),因为除去\(c\)后面的字符串长度为\(2\),所以答案就是\(ab\times p^2+cd=abcd\)

代码

#include <iostream>
using namespace std;
typedef unsigned long long ULL;
const int N = 2000010,BASE = 131;
int n;
char s[N];
ULL h[N],p[N];
void string_hash_prework () {
	p[0] = 1;
	for (int i = 1;i <= n;i++) {
		h[i] = h[i-1] * BASE + (s[i] - 'A' + 1);
		p[i] = p[i-1] * BASE;
	}
}
ULL query (int l,int r) {
	return h[r]-h[l-1]*p[r-l+1];
}
int main () {
	scanf ("%d%s",&n,s+1);
	if ((n & 1) == 0) printf ("NOT POSSIBLE");
	else {
		string_hash_prework ();
		int t = 0;
		ULL ans = 0;
		bool flag = false;
		for (int i = 1;i <= n;i++) {
			ULL h1,h2;
			if (i <= n/2) h1 = query (1,i-1)*p[n/2-i+1]+query (i+1,n/2+1);
			else h1 = query (1,n/2);
			if (i <= n/2+1) h2 = query (n/2+2,n);
			else h2 = query (n/2+1,i-1)*p[n-i]+query (i+1,n);
			if (h1 == h2) {
				if (flag && ans != h1) {
					printf ("NOT UNIQUE");
					return 0;
				}
				flag = true;
				ans = h1,t = i;
			}
		}
		if (!flag) printf ("NOT POSSIBLE");
		else {
			int cnt = 1;
			for (int i = 1;cnt <= n/2;i++) {
				if (i != t) {
					printf ("%c",s[i]);
					cnt++;
				}
			}
		}
		printf ("\n");
	}
	return 0;
}

标签:输出,le,样例,哈希,BalticOI,字符串,2014,friends
来源: https://www.cnblogs.com/incra/p/16454159.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有