传送门:All with Pairs

题意:给你n个字符串,求出,f(si,sj)的意思是字符串 s的前缀和字符串 s后缀最长相等部分。

题解:先对所有的字符串后缀hash,用map记录每个hash值(后缀)有多少个一样的。这个地方后缀的 hash 值可以将字符串倒过来求,每次乘以base^ i ,这和字符串正着求每次 t=t *base + s 是一样的,可以想象一下,前后缀相同位置乘base的次数是一样的。然后遍历所有的前缀的hash,在map里找当前 hash 值出现的次数的记录下来,最后把符合条件的长度平方乘以个数加起来,即ans+=mp[hash]* i * i。但是这样会有多算的部分,比如 f("aba","aba"),当遍历到 i=1 的时候,会加上一次,遍历到 i=3 的时候也会加上一次。这时应该选择 i=3的时候加上,把 i=1的时候舍去,这样就要用到kmp算法了,可以看出next[3]=1,只要在 i=3 的时候减去 next[3] 就好了。

  1. 1 #include<bits/stdc++.h>
  2. 2 #define ll long long
  3. 3 #define ull unsigned long long
  4. 4 #define pb push_back
  5. 5 #define ft first
  6. 6 #define sd second
  7. 7 #define pii pair<int,int>
  8. 8 #define pll pair<ll,ll>
  9. 9 using namespace std;
  10. 10
  11. 11 int nt[1000100];
  12. 12 int base=131;
  13. 13 const ull mod=998244353;
  14. 14 map<ull,int> mp;
  15. 15 string s[100100];
  16. 16 int res[1000100];
  17. 17
  18. 18 void kmp_nt(string p)
  19. 19 {
  20. 20 nt[0]=0;
  21. 21 for(int i=1,j=0;i<p.size();i++){
  22. 22 while(p[i]!=p[j]&&j) j=nt[j-1];
  23. 23 if(p[i]==p[j]) j++;
  24. 24 nt[i]=j;
  25. 25 }
  26. 26 }
  27. 27
  28. 28 void Hash(string s)
  29. 29 {
  30. 30 ull t=0,p=1;
  31. 31 for(int i=s.size()-1;i>=0;i--){
  32. 32 t+=p*(s[i]-'a'+1);
  33. 33 p*=base;
  34. 34 mp[t]++;
  35. 35 }
  36. 36 }
  37. 37
  38. 38 int main()
  39. 39 {
  40. 40 ios::sync_with_stdio(false);
  41. 41 cin.tie(0);
  42. 42 cout.tie(0);
  43. 43 int n;
  44. 44 cin>>n;
  45. 45 ll ans=0;
  46. 46 for(int i=0;i<n;i++) cin>>s[i],Hash(s[i]);
  47. 47 for(int i=0;i<n;i++){
  48. 48 ull t=0,p=1;
  49. 49 for(int j=0;j<s[i].size();j++){
  50. 50 t=t*base+s[i][j]-'a'+1;
  51. 51 res[j]=mp[t];
  52. 52 }
  53. 53 kmp_nt(s[i]);
  54. 54 for(int j=0;j<s[i].size();j++){
  55. 55 if(nt[j]) res[nt[j]-1]-=res[j];
  56. 56 }
  57. 57 for(int j=0;j<s[i].size();j++){
  58. 58 ans+=res[j]%mod*(j+1)%mod*(j+1)%mod;59 ans%=mod;
  59. 60 }
  60. 61 }
  61. 62 cout<<ans<<endl;
  62. 63 return 0;
  63. 64 }

2020牛客暑期多校训练营 (第二场) All with Pairs的更多相关文章

  1. 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学

    LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...

  2. 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论

    LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...

  3. 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路

    LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...

  4. 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心

    LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...

  5. 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...

  6. 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP

    LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...

  7. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  8. 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论

    LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...

  9. 2020牛客暑假多校训练营 第二场 G Greater and Greater bitset

    LINK:Greater and Greater 确实没能想到做法. 考虑利用bitset解决问题. 做法是:逐位判断每一位是否合法 第一位 就是 bitset上所有大于\(b_1\)的位置 置为1. ...

  10. 2020牛客暑假多校训练营 第二场 E Exclusive OR FWT

    LINK:Exclusive OR 没做出 原因前面几篇说过了. 根据线性基的知识容易推出 不超过\(w=log Mx\)个数字即可拼出最大值 其中Mx为值域. 那么考虑w+2个数字显然也为最大值.. ...

随机推荐

  1. IP包头分析

    • IP包头是IP协议(网络层,第三层)为数据包添加的头部.        ○ 格式:        ○ ○ 拆开看,每行是4+4+8+16=32bit=4Byte        ○ ip协议最短20 ...

  2. Head First 设计模式 —— 10. 迭代器 (Iterator) 模式

    思考题 public void printMenu() { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); ArrayList ...

  3. Goland 设置代码格式化

    前言 之前一直喜欢 VsCode 的代码自动格式化和其他的一些功能 今天了解到原来 Goland 也有这些功能, 想想也对, 毕竟这么大 正文 Goland设置代码格式化 进入设置,按需选择要使用的, ...

  4. kubernets之headless

    一  认识headless服务 1服务以及服务的作用相信大家都已经耳熟能详了吗,服务接受请求,并且随机的将请求转发到相关联的任一pod来处理请求,但是考虑另外一种场景, 如果有客户端需要知道这个服务关 ...

  5. 二进制部署kubernetes

    Kubernetes二进制安装 环境准备: 主机环境:做好主机名hosts文件映射 硬件2cpu  2G内存 192.168.30.21 k8s-master 192.168.30.22 k8s-no ...

  6. Ubuntu安装Vivado

    Step1 安装必要的库文件: sudo apt install libncurses5 build-essential openjdk-11-jdk Step2 进入vivado的安装文件夹 sud ...

  7. 数字化转型中企业真正困惑-传统IT架构如何改造和全面上云

    对数字化转型,整体来看大部分人相对关心问题主要还是集中在以下两个方面. 企业传统的IT架构如何如何微服务改造,演进发展 企业传统IT如何全面上云和实施云原生 以上两点实际都包括一个关键点,即企业当前内 ...

  8. echarts图表X轴文字过长解决解决方案:根据文字长度自动旋转

    Echarts 标签中文本内容太长的时候怎么办 ? 关于这个问题搜索一下,有很多解决方案.无非就是 省略(间隔显示).旋转文字方向.竖排展示 前面两种解决方案,就是echarts暴露的: {   ax ...

  9. axios用法

    1 axios.get('https://api.apiopen.top/getJoke?type=all', { 2 params: {//用于传参 3 type: 'all' 4 } 5 }).t ...

  10. git的使用学习笔记---合并分支

    一.使用场景 不同的分支需要合并 二.操作 1.首先要创建一个分支 git checkout -b mergedemo 创建文本 vim text.txt 添加文本 git add text.txt ...