Wannafly挑战赛10 F.小H和遗迹

青云算法面试题干货-字符串的子串-LeetCode第792题 问题:输入一个字符串S和一个字符串数组words,请问words中有多少个字符串是S的子序列?假设所有字符串都只含有小写英文字母。例如输入字符串S为"abcde",字符串输入words为["a", "bb", "acd", "ace"]。words中有三个字符串"a"、"acd"和"ace"都是S的子序列,因此正确的输出是3。 分析:这是LeetC 阅读详情
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

    小H在一片遗迹中发现了一种古老而神秘的文字,这种文字也由26种字母组成,小H用小写字母来代替它们。遗迹里总共有N句话,由于年代久远,每句话都至少有一处无法辨识,用#表示,缺失的可能是任意长度(也包括0)的任意字符串。
    小H发现这些话非常相似,现在小H想知道,有多少对句子可能是相同的
    注意:(x,x)这样的句子对不计入答案,(x,y),(y,x)视为同一个句子对(详见样例)

输入描述:

第1行,一个整数N
第2~N+1行,每行一个字符串表示一句话
2≤N≤500,000,所有字符串的总长不超过1,000,000

输出描述:

一行,一个整数,表示你给出的答案

思路:

    首先粘贴一段题解:

    定义两个字符串A,B“前相似”,当且仅当A是B的前缀或B是A的前缀

    定义两个字符串A,B“后相似”,当且仅当A是B的前缀或B是A的后缀

    先证明结论:两个字符串可能相同,当且仅当A和B在第一个#之前的部分前相似,并且A和B在最后一个#之后的部分后相似

    证明:结论的必要性显然,下证充分性

    1.首先可以将A和B在第一个#之前的部分、A和B在最后一个#之后的部分都去掉而不影响结果,原因是:不妨设A在第一个#之前的部分是B在第一个#之前的部分的前缀,则他们都可以变成B#的形式,后面的部分同理

    2.然后若A,B中有一个是单独的#,则显然成立

    3.否则A开头必然是#X#的形式(X是任意字符串),同理B开头是#Y#,则可以将#X和#Y去掉而不影响结果,因为他们都可以变成XY#的形式,这就可以转第2步递归构造,得证

    有了这个结论,我们可以把每个串在第一个#之前的部分和在最后一个#之后的部分分别插入到两棵Trie树中,两个串可能相同当且仅当他们对应的节点在两棵树上都是祖孙关系

    我们可以通过在第一棵Trie树上进行一次DFS求解,每到一个节点就先统计它在另一棵树上对应的点的祖先和子树上的所有点的和并计入答案,再将它在另一棵树上对应的点加一,整个过程可以用DFS序+两个树状数组实现,时间复杂度O((Σlen)*log(Σlen))

 

       这种前后缀插入两个Trie的思路算是一个很常见的套路了。之前大多是用一个字符串前后缀在相应Trie中dfs序作为一对坐标,然后计算一个矩形区域内点的个数。本题贡献的计算与之前有所不同,下面解释下题解中最后计算贡献的部分:

       我们先对后缀Trie做一个dfs序,然后对前缀Triedfs+回溯 计算贡献。对于前缀Trie上一个节点u,我们先找到其代表的字符串在后缀Trie上对应的节点v,这样贡献可以分为两部分计算,一部分是u的祖先集与v的后代集的交,另一部分是u的祖先集与v的祖先集的交,这样统计可以做到不重不漏。我们用两个树状数组分别计算这两部分贡献,每次对第一个树状数组L[v]的位置+1,这样当我们的遍历到u的时候,区间L[v]~R[v]的和就是第一部分贡献。第二个树状数组L[v]位置+1,R[v]+1位置-1,由于dfs序中v的祖先节点在v前,而v的兄弟节点在其区间中+1和-1相抵消,所以sum(L[v])即为第二部分贡献。


AC代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
#include <set>
#include <queue>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=1e6+5;

struct Trie {
	int cnt,ch[N][26];

	void init() {
		cnt=0;
		//memset(ch,0,sizeof(ch));
	}

	int insert(char *s,int op) {
		int l=strlen(s);
		int u=0,t=(op==1)?0:l-1;
		for(int i=t;;i+=op) {
			if(s[i]=='#') break;
			int c=s[i]-'a';
			if(!ch[u][c]) {
				ch[u][c]=++cnt;
			}
			u=ch[u][c];
		}
		return u;
	}
}pre,suf;

struct BIT {
	int m,bit[N];

	void init(int k) {
		m=k;
		//memset(bit,0,sizeof(bit));
	}

	void add(int i,int x) {
		for(;i<=m;i+=i&-i) {
			bit[i]+=x;
		}
	}

	int sum(int i) {
		int s=0;
		for(;i>0;i-=i&-i) {
			s+=bit[i];
		}
		return s;
	}
}b1,b2;

int n,u,v;
int pos,L[N],R[N];
char s[N];
vector<int> vc[N];
LL ans;

void dfs(int u) {
	L[u]=++pos;
	for(int i=0;i<26;i++) {
		int v=suf.ch[u][i];
		if(v) dfs(v);
	}
	R[u]=pos;
}

void cal(int u) {
	int v;
	for(int i=0;i<vc[u].size();i++) {
		v=vc[u][i];
		ans+=b1.sum(R[v])-b1.sum(L[v])+b2.sum(L[v]);
		b1.add(L[v],1);
		b2.add(L[v],1);
		b2.add(R[v]+1,-1);
	}
	for(int i=0;i<26;i++) {
		v=pre.ch[u][i];
		if(v) cal(v);
	}
	for(int i=0;i<vc[u].size();i++) {
		v=vc[u][i];
		b1.add(L[v],-1);
		b2.add(L[v],-1);
		b2.add(R[v]+1,1);
	}
}

void solve() {
	ans=0;pos=0;
	dfs(0);
	b1.init(pos);
	b2.init(pos);
	cal(0);
}

int main() {
	scanf("%d",&n);
	pre.init();
	suf.init();
	for(int i=1;i<=n;i++) {
		scanf("%s",s);
		u=pre.insert(s,1);
		v=suf.insert(s,-1);
		vc[u].push_back(v);
	}
	solve();
	printf("%lld\n",ans);
}



离散数学期末考试试卷(两套)-熟悉题型 3.设集合A={a,b,c,d}上有自反关系R={,,,,},对称关系S={,,,}。6.设集合A={1,2,3},B={u,v,w},C={a,b,c},f是集合A到集合B上的映射,g是集合B到集合C上的映射,f={, , },g={},则复合函数g。5. 设集合A={a,b,c,d,e},下列选项中哪一个集合不是A的划分( )。 阅读详情

相关推荐

银河麒麟V10离线环境下的Python项目迁移:从Windows依赖到ARM架构适配

本文详细介绍了在银河麒麟V10离线环境下将Python项目从Windows迁移到ARM架构的完整流程。重点讲解了离线安装pip、virtualenv等基础工具的方法,以及如何解决ARM架构兼容性问题,确保项目依赖正确迁移。文章还提供了常见问题解决方案和性能优化建议,帮助开发者顺利完成国产化平台适配工作。

weixin_42639246的博客 423

【每日一题】字符串

题目描述小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 输入描述:一行一个字符串S。只包含小写字母。S的长度不超过1e6. 输出描述:一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。 题解取尺法,定义l,r,向前枚举l,判断是否满足,如果不满足,将r向前移动,...

weixin_43802332的博客 966

使用amp训练出现Detected call of lr_scheduler.step() before optimizer.step().

这个警告是怎么产生的?是由于在算梯度的时候出现了nan,所以这一次更新会跳过,但是参数仍旧会更新所以出现了问题,按下面的做法加一个判断就行了。但是在使用amp进行混合精度训练出现的一个warning,调换代码顺序也不work。正常在训练的时候,对于优化器和参数更新的顺序这样就可以了。

weixin_46214675的博客 1306

字符串(牛客)

时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 输入描述: 一行一个字符串S。只包含小写字母。S的长度不超过106. 输出描述: 一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。 示例1 输入 复制

weixin_66170039的博客 834

论文笔记--Spatial-Temporal Fusion Graph Neural Networks for Traffic Flow Forecasting

Summary 在交通预测问题上,现有的框架通常利用给定的空间邻接图和复杂的机制来建模空间和时间关联。作者认为使用给定的空间邻接图会限制模型的有效时空相关性学习,并且它们通常使用单独的模块来实现空间和时间相关性,或者只使用独立的组件来捕获局部或全局的异质依赖关系,割裂了时空依赖关系。为此作者提出一种时空融合图神经网络用于交通预测。提出一种数据驱动的“时间图”生成方法,以此来补偿空间图可能没有反映的相关性。提出一种新的交通预测方法。 Problem Definition 交通预测中的挑战 以上图为

chenxino的博客 1755

mmpretrain学习笔记

(4)数据集路径 data_root=‘data/imagenet’–》data_root=‘data/Fruits Dataset/images’(7)适当的修改num_workers、epochs、batch_size、lr等。3、训练优化 :梯度下降算法、学习率参数、训练总轮次、学习率变化策略等。my_resnet18_8xb32_in1k.py 完整的配置文件。(6)split=‘train’、split='val’注释掉。2、数据:数据集划分、数据文件路径、批大小、数据增强策略等。

吃葡萄不吐葡萄皮 937

算法题-小H和迷宫(map函数,lambda函数,pop方法)

来源:牛客网。

xiaoliu_0168的博客 291

从零开始:Vivado中自定义串口通信IP核的完整实现

本文详细介绍了在Vivado中从零开始实现自定义串口通信IP核的完整流程,包括Verilog核心代码编写、仿真验证、IP核封装与参数化配置技巧。通过AXI-Lite总线实现动态配置,提升FPGA开发效率,适用于各种嵌入式系统通信需求。

weixin_29274969的博客 326

小H和迷宫(C++)

题目描述 ​ 小H陷入了一个迷宫中,迷宫里有一个可怕的怪兽,血量有N点,小H有三瓶魔法药水,分别可以使怪兽损失a%、b%、c%的血量(之后怪兽的血量会向下取整),小H想合理地运用这三瓶药水,使怪兽失去尽可能多的血量 ​ 注意:每瓶药水只能用一次 输入描述: 一行,四个整数 N,a,b,c 输出描述: 一行,一个整数w,表示最多能使得怪兽扣减多少血量 示例1 输入 100 20 15 0 输出 32 备注: 5≤N≤109,0≤a,b,c≤100 暴力+排序 代码: #include

liuzich的博客 787

innovus中path group 的策略和应用(上)

在所有的后端工具里边,有三个重要的引擎:auto-place,CTS,auto-route三个。这里边的auto-place是决断了整个设计时序的基点。。当然,就算是到了CTS/route阶段后,也可以继续利用auto-place数据优化的功能,在数据库上做数据路径增量优化(optDesign -increment)。可以说,数据路径的优化手段,实际上是贯穿在整个后端流程上的。。看看这其中的奥妙和有趣的事情。ICer GO!

i_chip_backend的博客 4220

uniapp [安卓苹果App端] - 实现支付宝支付功能+拉起支付宝app付款支付后返回跳转到原页面,详解uniApp如何唤起本机支付宝并跳转到支付页面全流程及示例源码(APP端支付宝支付,支持打包

全网最详细的uniapp支付宝支付教程,uniapp支付宝支付流程,uni-app项目在APP端使用支付宝支付功能,uniapp前端实现支付宝支付,uniapp中唤醒支付宝进行支付并返回app,uniApp调起支付宝支付失败报错,uniapp app端调支付宝支付接口,uniapp开发安卓App对接支付宝支付,uniapp苹果ios唤起支付宝支付,uniapp调用支付宝支付uniapp开发app-调用支付宝支付,uniapp开发安卓苹果app如何接入支付宝支付,UniApp中实现支付宝支付功能,支付报错,调

🏆 前端领域优质创作者 1万+

小H和迷宫

链接:https://ac.nowcoder.com/acm/problem/15156 来源:牛客网 题目描述 小H陷入了一个迷宫中,迷宫里有一个可怕的怪兽,血量有N点,小H有三瓶魔法药水,分别可以使怪兽损失a%、b%、c%的血量(之后怪兽的血量会向下取整),小H想合理地运用这三瓶药水,使怪兽失去尽可能多的血量 注意:每瓶药水只能用一次 输入描述: 一行,四个整数...

huantingyizhan的博客 1万+

SAP自动化-ME51N批量创建采购申请

2、需要管理员授权RZ11脚本录制回放功能。1、仅限于正对SAP日常工作的批量处理。3、数据模板按实际需求更新。物料编码,工厂,数量。

小九啥也不会 530

Wannafly挑战赛10F-小H和遗迹【Trie,树状数组】

正题 题目链接:https://ac.nowcoder.com/acm/contest/72/F 题目大意 nnn个字符串,包括小写字母和#\##。其中#\##可以替换为任意字符串。求有多少对字符串可能相同。 保证每个字符串至少有一个#\##。 2≤n≤500000,∑i=1n∣si∣≤1062\leq n\leq 500000,\sum_{i=1}^n |s_i|\leq 10^62≤n≤500000,∑i=1n​∣si​∣≤106 解题思路 因为可以替换为任意字符串,所以只需要考虑第一个#\##前和

QuantAsk 355

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

字符串

小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 输入描述: 一行一个字符串S。只包含小写字母。S的长度不超过1e6. 输出描述: 一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。 输入 ykjygvedtysvyymzfizzwkjamefxj...

codertcm的博客 449

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

牛客Wannafly挑战赛10 A.小H和迷宫

链接:https://www.nowcoder.com/acm/contest/72/A来源:牛客网题目描述 小H陷入了一个迷宫中,迷宫里有一个可怕的怪兽,血量有N点,小H有三瓶魔法药水,分别可以使怪兽损失a%、b%、c%的血量(之后怪兽的血量会向下取整),小H想合理地运用这三瓶药水,使怪兽失去尽可能多的血量 注意:每瓶药水只能用一次输入描...

weixin_30307267的博客 212

c++算法基础必刷题目——尺取法

尺取法比直接暴力枚举区间效率高很多,尤其是数据量大的时候,所以说尺取法是一种高效的枚举区间的方法,是一种技巧,一般用于求取有一定限制的区间个数或最短的区间等等。牛客幼儿园的小朋友们围成了一个圆圈准备玩丢手绢的游戏,但是小朋友们太小了,不能围成一个均匀的圆圈,即每个小朋友的间隔可能会不一致。1、开始,l和r都在a点,目前不是最优状态,r往顺时针方向走到b,目前也不是最优状态,r往顺时针方向走到c,达到最优状态,记录答案。接下来的第2到第n行,第i行有一个整数,表示第i-1个小朋友顺时针到第i个小朋友的距离。

weixin_52115456的博客 1097

小H和游戏——dfs序+树状数组 | 思维

题目链接:https://ac.nowcoder.com/acm/contest/5203/D 题目大意: 给你一棵n个节点的树,然后有q次轰炸,每次轰炸可以波及到与当前节点距离小于等于2的节点,并输出该次轰炸后当前节点的被轰炸次数。 题解: 解法一:树状数组(线段树)+dfs序 这个题先讲相对而言时间复杂度比较高的解法,但是比较好想,容易理解。 首先我们可以求出每个点的儿子编号...

mumei的博客 353

【牛客161 - A】字符串(尺取法,桶标记法)

题干: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 输入描述: 一行一个字符串S。只包含小写字母。S的长...

xuanweiace的博客 1274

取尺法(书上P146)

易懂的题解链接 就是相当于移动左右指针,反复推进区间的开头和末尾(相当于左右端点可变化的尺子),求满足条件的最小区间。 牛客网: 板子题 小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 输入 ykjygvedtysvyymzfizzwkjamefxjnrnphqwnfhrnbhwjhqcgqnplodeestuykjygvedtysvyymzfizzwkjamefxjnrn

m0_52075409的博客 496

牛客__小H和遗迹

链接:https://ac.nowcoder.com/acm/problem/15160 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64bit IO Format: %lld 题目描述 小H在一片遗迹中发现了一种古老而神秘的文字,这种文字也由26种字母组成,小H用小写字母来代替它们。遗迹里总共有N句话,由...

cgtllp1的博客 390

字符串 (包含T全部元素的最小窗口)

链接:https://www.nowcoder.com/acm/contest/161/A 来源:牛客网   题目描述 小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 链接:https://www.nowcoder.com/acm/contest/161/A 来源:牛...

海绵的博客 628

小H和遗迹(trie+dfs序+树状数组)

链接:https://ac.nowcoder.com/acm/problem/15160来源:牛客网 题目描述 小H在一片遗迹中发现了一种古老而神秘的文字,这种文字也由26种字母组成,小H用小写字母来代替它们。遗迹里总共有N句话,由于年代久远,每句话都至少有一处无法辨识,用#表示,缺失的可能是任意长度(也包括0)的任意字符串。 小H发现这些话非常相似,...

diaomeijiao3430的博客 320

Wannafly挑战赛23 A字符串 (求最短的子串包含所有小写字母)尺取法

题目链接 https://www.nowcoder.com/acm/contest/161/A 题意 小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 题解 尺取法。 枚举区间的较高效的方法。 先初始化区间为[0,-1]. 然后找到右区间r,使得区间[l,r]...

EnjoyingAC的博客 754

牛客挑战赛23-A.字符串(尺取)

小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 输入描述: 一行一个字符串S。只包含小写字母。S的长度不超过106. 输出描述: 一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。 示例1 输入 ykjygvedtysvyymzfizzwkja...

PleasantlY1的博客 764

牛客网-每日一题-字符串-尺取法

链接:https://ac.nowcoder.com/acm/problem/18386 来源:牛客网 题目描述 小N现在有一个字符串S。他把这这个字符串的所有子串都挑了出来。一个S的子串T是合法的,当且仅当T中包含了所有的小写字母。小N希望知道所有的合法的S的子串中,长度最短是多少。 输入描述: 一行一个字符串S。只包含小写字母。S的长度不超过106. 输出描述: 一行一个数字,代表最短长度。数据保证存在一个合法的S的子串。 示例1 输入 复制 ykjygvedtysvyymzfizzwkjamefxjn

我不吃海鲜的博客 552

Wannafly挑战赛10:A题:小H和迷宫

题目描述 小H陷入了一个迷宫中,迷宫里有一个可怕的怪兽,血量有N点,小H有三瓶魔法药水,分别可以使怪兽损失a%、b%、c%的血量(之后怪兽的血量会向下取整),小H想合理地运用这三瓶药水,使怪兽失去尽可能多的血量 注意:每瓶药水只能用一次 输入描述: 一行,四个整数 N,a,b,c 输出描述: 一行,一个整数w,表示最多能使得怪兽扣减多少血量...

weixin_30832405的博客 364
上一篇: Sublime Text 3在Windows下配置C++环境
AC_Machine
博客等级 码龄11年 1粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值