【题解&比赛总结】NOIP 2020正式赛 字符串匹配 (string)

题面

在这里插入图片描述

Sample Input

3
nnrnnr
zzzaab
mmlmmlo

Sample Output

8
9
16

数据范围

在这里插入图片描述

题解

First of All

我们首先先考虑一个朴素的暴力算法:
我们枚举一个 A B AB AB,然后求出 ( A B ) i (AB)^i (AB)i 那么此时 C C C 也就确定了。
然后我们再枚举出A,然后判断是否可行,统计答案即可
时间复杂度 θ ( T n 3 ) \theta(Tn^3) θ(Tn3)

优化

我们发现这个方法的时间复杂度实在是难以令人接受了。
我们考虑优化。
枚举AB是少不了的了。
那我们看看如何优化求 ( A B ) i (AB)^i (AB)i,我们可以枚举 i i i,然后用hash简单判断一下就好了。
由于出题人没有卡hash的念头,因此单hash即可。
然后我们再看如何统计答案
我们可以设 s u m i , j sum_{i,j} sumi,j 表示前 i i i 个位置奇数字母的个数<=j的位置个数。
接着我们发现这可以边做边求。
然后便有了这个做法。时间复杂度 θ ( T n l n ( n ) + 26 n ) \theta(Tnln (n)+26n) θ(Tnln(n)+26n)

Code
#include<cstdio>
#define ll long long
using namespace std;
const ll P=402653189;
const ll seed=131;
const int N=2e6+5;
char s[N];
ll ans;
int n,tot;
ll hash[N],p[30],sum[N][30],js[N],jc[N];
bool pd(int l,int r,int l2,int r2){
   
	ll h1=(hash[r]-hash[l-1]*jc[r-l+1]%P+P)%P;
	ll h2=(hash[r2]-hash[l2-1]*jc[r2-l2+1]%P+P)%P;
	if (h1==h2) return 1;
	return 0;
}
int main
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值