当前位置: 首页 > news >正文

子串分值【第十一届】【省赛】【A组】

问题描述

对于一个字符串 s,我们定义 s 的分值 f(s) 为 s 中恰好出现一次的字符个数。例如 f("aba")=1,f("abc")=3, f("aaa")=0。

现在给定一个字符串 s[0..n−1](长度为 n),请你计算对于所有 s 的非空子串 s[i..j](0≤i≤j<n),f(s[i..j])的和是多少。

输入格式

输入一行包含一个由小写字母组成的字符串 s。

输出格式

输出一个整数表示答案。

样例输入

ababc

样例输出

21

样例说明

子串  f值
a     1
ab    2
aba   1
abab  0
ababc 1b    1ba   2bab  1babc 2a   1ab  2abc 3b  1bc 2c 1

评测用例规模与约定

对于 20% 的评测用例,1≤n≤10;

对于 40% 的评测用例,1≤n≤100;

对于 50% 的评测用例,1≤n≤1000;

对于 60% 的评测用例,1≤n≤10000;

对于所有评测用例,1≤n≤100000。

题解:

        通俗地说,题目的要求就是给定一个字符串,要求求出这个字符串所有子串的分值,而对于一个字符串来说,它的分值就等于自身包含的所有字符中出现且仅出现了一次的字符个数

        顺着题意来的话,多数人应该会想要把给定字符串的子串全部枚举出来,然后再数每个子串中只出现了一次的字符的个数,这样做需要枚举所有的左右边界,计算的时间复杂度为O(n^2),必然会超时。

        下面介绍的是O(n)的做法:

        题目要求的分值是所有子串分值的总和,并且对于相同的字母a,如果它在不同的位置,它也算是不同的字母,比如给定字符串“aba”,他有子串‘a'和‘a’,两个‘a’在不同的位置。所以我们不需要计算所有子串的分值,只需要计算每一个字母作为只出现一次的字符时,包含了该字母的子串的个数,假如说现在给定一个字符串“abcadcada”,现在讨论字母a的分值,则可以把该字符串看成“a..bc..a..dc..a..d..a”,则对于第二个字母a,它的有效子串的个数9,分别为bca,ca,a,bcad,cad,ad,bcadc,cadc,adc;其实同样也是枚举左右边界,左边界有三种选择b、c、a,右边界有三种选择a、d、c,两两组合,组合数为3*3=9。对于其它字母也是同样的计算有效子串的个数,最终求解它们的和。

      用一个数组pre[]预处理位于i左侧的和第i个字母相同的最近的一个字母的位置,“a..bc..a..dc..a..d..a”,对于第二个a来说,它是第四个字符,所以pre[4]=1;用一个数组next[]预处理位于i右侧的和第i个字母相同的最近的一个字母的位置,对于第二个a来说,next[4]=7.

        所以左边界的选择数其实就等于“a..bc..a..dc..a..d..a”中bca的长度,右边界的选择数就等于“a..bc..a..dc..a..d..a”中adc的长度,转化为代码就是i - pre[i]和next[i] - i,将两者相乘,得到第二个子串的有效子串数。

        在预处理pre和next数组时,会借助一个idx数组,由于题中给出的字符串都由小写字母组成,我们可以把每个字母都通过ascii码相减转化为数字也就是,x-'a',例如,‘b’-‘a’=1。所以idx[1]就表示上一个b出现的位置。

 结合代码:

#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10, M = 50;
int pre[N], nex[N], idx[M];int main()
{string s; cin >> s;int len = s.size();s = ' ' + s;//计算pre[i]for (int i = 1; i <= len; i++) {pre[i] = idx[s[i] - 'a'];idx[s[i] - 'a'] = i;}//初始化右超界为n+1for (int i = 0; i < 26; i++) {idx[i] = len + 1;}//计算next[i]for (int i = len; i > 0; i--) {nex[i] = idx[s[i] - 'a'];idx[s[i] - 'a'] = i;}ll ans = 0;for (int i = 1; i <= len; i++) {ans += (i - pre[i]) * (nex[i] - i);}cout << ans;return 0;
}

http://www.lryc.cn/news/684.html

相关文章:

  • SpringCloud 中 Config、Bus、Stream、Sleuth
  • Quantum 构建工具使用新的 TTP 投递 Agent Tesla
  • 浏览器中的 JavaScript 执行机制
  • kafka集群搭建及问题
  • 不要忽视web渗透测试在项目中起到的重要性
  • Early Stopping中基于测试集(而非验证集)上的表现选取模型的讨论
  • appium ios真机自动化环境搭建运行(送源码)
  • 米尔基于ARM嵌入式核心板的电池管理系统(BMS)
  • Java后端项目IDEA配置代码规范检查,使用checkStyle实现
  • Nginx_4
  • linux Ubuntu KUbuntu 系统安装相关
  • 个人信息保护认证
  • Negative Prompt in Stable Diffusion
  • MLX90316KGO-BDG-100-RE传感器 旋转位置 角度测量
  • Reflections反射包在springboot jar环境下扫描不到class排查过程
  • 黑马】后台项目171集
  • Qt 5 架构和特点
  • 转换符说明使用方法(在printf函数中)
  • 针灸-基本任脉督脉
  • 信息系统与信息化
  • 解决axios异步请求问题(异步变为同步)
  • 【Django】云笔记项目
  • LeetCode——1797. 设计一个验证系统
  • java Resource
  • ArkTS语法(声明式UI)
  • 自动化测试实战篇(7)jmeter连接mysql数据库,实现单表、多表、三表查询,并对表中数据进行修改,删除,新增操作
  • 我的网站上线了!
  • 勒索病毒整体攻击态势简单分析
  • Vue资源(组件库、实用插件)
  • java rpc框架 中的自定义异常类型的全局处理