链接:https://ac.nowcoder.com/acm/problem/19822
来源:牛客网

题目描述
终于活成了自己讨厌的样子。

天空仍灿烂,它爱着大海。

你喜欢大海,我爱过你。

世界上充满了巧合。我们把每句话当成一个字符串,我们定义a对b的巧合值为a的最长后缀的长度并且它是恰好是b的前缀,这里的后缀或者前缀包括字符串的本身。
比如字符串“天空仍灿烂她喜欢大海”对“她喜欢大海我不爱她了我爱的只是与她初见时蔚蓝的天空”的巧合值为5,而字符串“她喜欢大海我不爱她了我爱的只是与她初见时蔚蓝的天空”对“天空仍灿烂她喜欢大海”的巧合值为2。
现在给出n个字符串由"ab"构成的字符串s1,s2,…,sn,求出对于所有1≤ i,j≤ n,si对sj的巧合值的和。

即求对于每个字符串的前缀,找到对于每个字符串最长匹配的后缀的长度和。

容易想到用hash匹配,可以把复杂度控制在O(∑∣S∣\sum|S|∑∣S∣)。
具体的,读入字符串时首先把每个后缀对应的hash存在map内,统计对应hash的个数,再次遍历前缀时只要加上对应hash个数乘长度即可。

后面就是我觉得这个题目的有趣之处。如上做法会造成重复计算,对于极端样例aaaaaaa明显会计入多次。那么我们就要去重,我第一次想的是容斥去重,发现并不可行,看了题解做法kmp+hash,再回来看,我们发现对于ababa,如果最后一个a跟别人匹配了,那么首先ababa的前缀aba与后缀aba是匹配的,所以对于匹配的那个字符串来说,ababa的后缀必定与前缀也就是我们当前子串的后缀匹配(有点晕,这里建议不看,自己退一退简单多了。),由此,我们可以知道重复计算的串也就是满足kmp匹配规则的前后缀,对于next数组值不为0的,我们只要res[next[j]] -= res[j]即可,res是当前长度对应后缀hash的个数。如果不知道next数组意思的可以,可以理解为字符串的[1~next[i]]与[len-next[i]+1,len]完全匹配。

#include "bits/stdc++.h"#define int long long
using namespace std;
const int N = 2e6 + 10;
#define Pii pair<int,int>
int h[N];
int p[N];
int nxt[N];
unordered_map<int, int> sf;
void search(string s)
{int k=-1;nxt[0]=-1;int j=0;while(j<s.length()){if(k<0 || s[k]==s[j]){j++;k++;nxt[j] = k;}else {k=nxt[k];}}
}
int getHash(int l, int r) {return h[r] - h[l - 1] * p[r - l + 1];
}int res[N];
string str[N];
void solve() {p[0] = 1;for (int i = 1; i < N; ++i) {p[i] = p[i - 1] * 13;}int T;cin >> T;while (T--) {sf.clear();int n;cin >> n;for (int i = 1; i <= n; ++i) {cin >> str[i];int len = str[i].length();h[0] = 1;for (int j = 1; j <= len; ++j) {int id = j - 1;h[j] = h[j - 1] * 13 + str[i][id] - 'a' + 1;}for (int j = 1; j <= len; ++j) {sf[getHash(len - j + 1, len)]++;}}int ans = 0;for (int i = 1; i <= n; ++i) {int len = str[i].length();h[0] = 1;for (int j = 1; j <= len; ++j) {int id = j - 1;h[j] = h[j - 1] * 13 + str[i][id] - 'a' + 1;res[j] = sf[getHash(1,j)];}search(str[i]);for (int j = 1; j <= len; ++j) {if (nxt[j]) res[nxt[j]] -= res[j];}for (int j = len; j >= 1; --j) {ans += res[j] * j;}}cout << ans << endl;}}signed main() {//    freopen("in.txt", "r", stdin);ios::sync_with_stdio(0);solve();
}

NC19822 我不爱她 kmp+hash相关推荐

  1. UVA 11557 - Code Theft (KMP + HASH)

    UVA 11557 - Code Theft 题目链接 题意:给定一些代码文本.然后在给定一个现有文本,找出这个现有文本和前面代码文本,反复连续行最多的这些文本 思路:把每一行hash成一个值.然后对 ...

  2. KMP,HASH,Trie,AC自动机

    我做个总结算了下午看了一下AC自动机和学习我的大生物(当然是多谢鑫神了)..完了要崩.. 1 KMP 只要是学过的人都觉得比较简单吧 但是学不会的人就感觉很难了,我是那种顿悟的然后感觉非常简单的人过程 ...

  3. 各种模板(数学数论字符串)

    文章目录 数学&数论 线性求逆元 exgcd excrt FFT NTT 矩阵乘法 线性筛素数 杜教筛 字符串 Trie KMP hash Manacher AC自动机 PAM SAM 广义S ...

  4. 2020牛客暑假多校第二场补题

    比赛链接:link 题目 A kmp + Hash B 几何 C dfs D 签到题 F 单调区间 + gcd筛 G bitset神奇用法 H 权值线段树(动态开点/离散化) J 群论     A k ...

  5. 8.6 正睿暑期集训营 Day3

    目录 2018.8.6 正睿暑期集训营 Day3 A 亵渎(DP) B 绕口令(KMP) C 最远点(LCT) 考试代码 A B C 2018.8.6 正睿暑期集训营 Day3 时间:5h(实际) 期 ...

  6. 【笔记】震惊!世上最接地气的字符串浅谈(HASH+KMP)

    震惊!世上最接地气的字符串浅谈(HASH+KMP) 笔者过于垃圾,肯定会有些错的地方,欢迎各位巨佬指正,感激不尽! 引用:LYD的蓝书,一本通,DFC的讲稿,网上各路巨佬 Luguo id: 章鱼那个 ...

  7. SZUACM集训字符串基础总结: 字符串最小表示 ,KMP, EXKMP, Manracher, Trie树,字符串的hash; 附带一写常见的运用技巧,邝斌大佬的板子和例题[持续更新]

    第一部分 字符串的匹配<-------->KMP 模式匹配:子串的定位运算称为串的模式匹配或串匹配. 假设有两个串S,T,设S为主串,也称正文串,T为子串,也称为模式,在主串S中查找与模式 ...

  8. 【牛客OI周赛7-普及组ABCD 非官方题解】暴力,二分,KMP,尺取(STL或Hash)

    A: 链接:https://ac.nowcoder.com/acm/contest/372/A 来源:牛客网 某天,一只可爱的肥橘喵在路上走,突然遇到了一个怪人,那怪人自称PM6,"小肥喵, ...

  9. SCU4438 Censor(审查员) (KMP算法与模拟栈的应用 || HASH表与模拟栈的结合)

    Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text pp. Her j ...

最新文章

  1. Struts的ONGL
  2. Factorial Trailing Zeroes
  3. canvas 实现图片局部模糊_JavaScript中的图片处理与合成(四)
  4. html 广告 ins 原理,如何通过HTML DOM元素显示AdSense广告
  5. 【工具使用】apizza和postman中post请求下form-data、x-www-form-urlencoded、raw、binary的区别
  6. PostgreSQL 10.1 手册_部分 I. 教程
  7. 磁滞回线与软磁材料和硬磁材料的关系
  8. eemd优缺点_改进EEMD算法在心电信号去噪中的应用
  9. java正则表达式逗号_java – 接受逗号或分号分隔值的正则表达式模式
  10. 制作可被svchost调用的服务(下)
  11. 【孵化器系列采访】创新工场:高端人才成功创业的聚集地
  12. CSS尺寸与文本讲解。HTML、CSS笔记(四)。
  13. Python 基于OpenCV 在一张图片上叠加点
  14. 步进电机的使用教程以及步距角和细分讲解
  15. qq2007bate3协议分析
  16. Luogu 2495 [SDOI2011]消耗战
  17. java实现远程登录RDP
  18. 声学多普勒流速剖面仪_声学多普勒流速剖面仪ADCP
  19. 一金创投月薪几万怎样出资理财 月薪几万怎样出资保值
  20. 图书管理系统--新增图书

热门文章

  1. 用Java写一个年薪计算器,助你简单完成大量税前税后总薪计算量
  2. 本科进了大厂拿高薪,为什么硕士和博士却要挤破头进高校?
  3. 「Slack」- 安装 @20210303
  4. abb式c语言,ABB机器人是用什么语言编程的? ——ABB机器人
  5. 实操石英钟改5V充电器供电
  6. 技术指南:手机拍照身份证识别技术
  7. gitlab密码忘了怎么办?
  8. python红楼梦人物统计_基于共现使用Python来分析《红楼梦》中贾宝玉与金陵十二钗的关系...
  9. Creo 9.0安装教程
  10. 微信如何添加企业微信信息服务器地址,企业微信怎么添加管理员 设置方法介绍...