1459 Baltic2014 friends(LUOGU6739 LOJ2823 难度:普及+/提高) 被动取模 自然溢出 滚动哈希 无符号整数 B进制数 文火慢炖

总目录

在线测评地址(ybt)

在线测评地址(LOJ)

在线测评地址(LUOGU)

思路:

若N是偶数,则S不存在。

若N是奇数,去除一个字母,看剩下的前后两个字串是否相等。

因26个大写字母,故B取29.

该题的难点在于拼接字符串。

有人提出,采用除运算,将尾部字母去除,请注意,这是不行的,在模运算中,除法是不能轻易用的,否则,干嘛要学乘法逆元。

如何求解某段子串,请看哈希值生成过程

字符串ABCDEFG
哈希值生成过程
ah[1] A
ah[2] AB
ah[3] ABC
ah[4] ABCD
ah[5] ABCDE
ah[6] ABCDEF
ah[7] ABCDEFG

去除某个字母,剩下两子串生成过程
(A)BCDEFG
BCD EFG子串生成:
EFG 等价于ah[7]-ah[4]*n[3]
BCD 等价于ah[4]-a[1]*n[3]

A(B)CDEFG
ACD EFG子串生成:
EFG 等价于ah[7]-ah[4]*n[3]
ACD 等价于ah[1]*n[2]+ah[4]-ah[2]*n[2]

AB(C)DEFG
ABD EFG子串生成:
EFG 等价于ah[7]-ah[4]*n[3]
ABD 等价于ah[2]*n[1]+ah[4]-ah[3]*n[1]

......

ABCDEF(G)
ABC DEF子串生成:
ABC 等价于ah[3]
DEF 等价于ah[6]-ah[3]*n[3]

文火慢炖:

删除的字母位置在i,i在前半段

删除的字母位置整个字串的正中央 

删除的字母位置在i,i在后半段

上述3种情况的讨论,是靠着数据一点一点的算出来的,提供几组数据如下:

7
XABCABC

7
AXBCABC

7
ABXCABC

7
ABCXABC

7
ABCAXBC

7
ABCABXC

7
ABCABCX

上述数据均属出

ABC

关键测试数据

输入数据:
7
AAAAAAA

输出数据:
AAA

洛谷中若WA#50#53#59#61#64

请注意题目中有这样一段话:

如果从 U 得到的 S 不是唯一的,输出 NOT UNIQUE

也就是说,如果能得到唯一的解,即使有多种删去可能,也要输出答案,而不是NOT UNIQUE!!!!!

上面的关键测试数据  就是上述说法的具体实施。

AC代码:

ybt

通过

测试点结果内存时间
测试点1答案正确340KB1MS
测试点2答案正确336KB1MS
测试点3答案正确340KB0MS
测试点4答案正确340KB0MS
测试点5答案正确340KB0MS
测试点6答案正确344KB0MS
测试点7答案正确340KB1MS
测试点8答案正确340KB0MS
测试点9答案正确340KB0MS
测试点10答案正确340KB0MS
测试点11答案正确340KB0MS
测试点12答案正确344KB0MS
测试点13答案正确344KB0MS
测试点14答案正确340KB0MS
测试点15答案正确344KB0MS
测试点16答案正确340KB0MS
测试点17答案正确340KB0MS
测试点18答案正确340KB0MS
测试点19答案正确340KB0MS
测试点20答案正确340KB0MS
测试点21答案正确344KB0MS
测试点22答案正确340KB0MS
测试点23答案正确340KB0MS
测试点24答案正确340KB0MS
测试点25答案正确332KB0MS
测试点26答案正确340KB0MS
测试点27答案正确340KB0MS
测试点28答案正确340KB0MS
测试点29答案正确344KB0MS
测试点30答案正确340KB0MS
测试点31答案正确340KB0MS
测试点32答案正确348KB0MS
测试点33答案正确336KB0MS
测试点34答案正确340KB0MS
测试点35答案正确340KB0MS
测试点36答案正确344KB0MS
测试点37答案正确336KB0MS
测试点38答案正确336KB0MS
测试点39答案正确344KB0MS
测试点40答案正确344KB0MS
测试点41答案正确344KB0MS
测试点42答案正确340KB0MS
测试点43答案正确336KB0MS
测试点44答案正确380KB1MS
测试点45答案正确368KB1MS
测试点46答案正确372KB1MS
测试点47答案正确376KB1MS
测试点48答案正确368KB1MS
测试点49答案正确336KB0MS
测试点50答案正确368KB1MS
测试点51答案正确376KB1MS
测试点52答案正确376KB1MS
测试点53答案正确364KB1MS
测试点54答案正确368KB1MS
测试点55答案正确33532KB79MS
测试点56答案正确33532KB78MS
测试点57答案正确33532KB78MS
测试点58答案正确33532KB78MS
测试点59答案正确33528KB78MS
测试点60答案正确2284KB12MS
测试点61答案正确33532KB80MS
测试点62答案正确30220KB35MS
测试点63答案正确30216KB70MS
测试点64答案正确30220KB70MS
测试点65答案正确28008KB32MS

LOJ

LUOGU

 

AC代码如下:

#include <cstdio>
#include <cstring>
#define maxn 2000010
#define B 29
#define ULL unsigned long long
using namespace std;
char a[maxn];
int an;
ULL ah[maxn],n[maxn],b=0;
int main(){
	int N,i,j,tot,len,k=0;
	scanf("%d%s",&N,a+1);
	if(N%2==0){//N是偶数 
		printf("NOT POSSIBLE\n");
		return 0;
	}
	an=strlen(a+1);
	n[0]=1;
	for(i=1;i<=an;i++)n[i]=n[i-1]*B;
	ah[0]=0;
	for(i=1;i<=an;i++)ah[i]=ah[i-1]*B+a[i]-'A'+1;
	tot=0;
	len=an/2; 
	for(i=1;i<=an/2;i++){//删除的字母位置在i,i在前半段
		if(ah[an]-ah[an-len]*n[len]==ah[i-1]*n[len-(i-1)]+ah[len+1]-ah[i]*n[len-i+1]){//此行代码耗费心力
			k=i,tot++;
			if(!b)b=ah[an]-ah[an-len]*n[len];
			else if(b!=ah[an]-ah[an-len]*n[len]){
				printf("NOT UNIQUE\n");
				return 0;
			}
		}
	}
	if(ah[len]==ah[an]-ah[an-len]*n[len]){//删除的字母位置整个字串的正中央 
		k=len+1,tot++;
		if(!b)b=ah[len];
		else if(b!=ah[len]){
			printf("NOT UNIQUE\n");
			return 0;
		}
	}
	for(i=an/2+2;i<=an;i++){//删除的字母位置在i,i在后半段
		if(ah[len]==(ah[i-1]-ah[len]*n[(i-1)-len])*n[an-i]+ah[an]-ah[i]*n[an-i]){//此行代码耗费心力
			k=i,tot++;
			if(!b)b=ah[len];
			else if(b!=ah[len]){
				printf("NOT UNIQUE\n");
				return 0;
			}
		}
	}
	if(tot==0)printf("NOT POSSIBLE\n");
	else{
		if(k<=an/2+1){
			for(i=an/2+2;i<=an;i++)printf("%c",a[i]);
			printf("\n");
		}else{//k>an/2+1
		 	for(i=1;i<=an/2;i++)printf("%c",a[i]);
		 	printf("\n");
		}
	}
	return 0;
}

该题编码比较耗时的,对于哈希值的理解,是更上了一层楼了。此题必刷。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值