LINK


考虑把所有串建立ACAMACAMACAM

那么其实问题等价于

计算ttt串的每个前缀中,有多少后缀匹配多少si+sjs_i+s_jsi​+sj​的形式

于是现在我们单独对每一个前缀来计算答案

我们预处理一个ok[x]ok[x]ok[x]表示节点xxx能通过failfailfail边转移到多少个单词

那么设x1,x2x_1,x_2x1​,x2​都是串ttt的前缀节点,∣x1∣,∣x2∣|x_1|,|x_2|∣x1​∣,∣x2​∣分别表示这两个前缀的长度

x2x_2x2​通过跳failfailfail变能到一个长度为kkk的单词,且满足∣x2∣−k=∣x1∣|x_2|-k=|x_1|∣x2​∣−k=∣x1​∣

那么答案自然可以加上ok[x1]ok[x_1]ok[x1​]

于是有代码LINK


不难发现这样暴力跳failfailfail,是不合理的,2∗1052*10^52∗105个′a′'a'′a′就会被卡死了

设ttt串的某个前缀节点是xxx,不妨考虑ok[x]ok[x]ok[x]被计算多少次

ok[x]ok[x]ok[x]被计算的次数,就是[x+1,∣t∣][x+1,|t|][x+1,∣t∣]所有前缀被匹配的次数

前缀是算不了的,ACAMACAMACAM只能计算后缀…

所以我们再把ttt的反串也插入ACAMACAMACAM,那么反串的后缀就是正串的前缀嘛!!

同时注意,ttt的正串和反串需要分别建立自动机,因为反串自动机插入的字符串也必须是反的

因为匹配的时候是在拿反串匹配

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 4e5+10;
int n,ID[maxn];
char t[maxn],s[maxn],ft[maxn];
struct ACAM
{int ok[maxn],fail[maxn],zi[maxn][26],id;void insert(char a[],int val){int len = strlen( a+1 ), now = 0;for(int i=1;i<=len;i++){if( !zi[now][a[i]-'a'] )    zi[now][a[i]-'a'] = ++id;now = zi[now][a[i]-'a']; }ok[now]+=val;}void get_fail(){queue<int>q;for(int i=0;i<=25;i++)if( zi[0][i] )    q.push( zi[0][i] );while( !q.empty() ){int u = q.front(); q.pop();ok[u] += ok[fail[u]];for(int i=0;i<=25;i++){if( zi[u][i] )  fail[zi[u][i]] = zi[fail[u]][i],q.push( zi[u][i] );else    zi[u][i] = zi[fail[u]][i];}}}
}T1,T2;
signed main()
{scanf("%s",t+1 ); int l = strlen( t+1 ); for(int i=1;i<=l;i++) ft[i] = t[l-i+1]; T1.insert( t,0 );  T2.insert( ft,0 );cin >> n;for(int i=1;i<=n;i++){scanf("%s",s+1 ),T1.insert( s,1 );reverse(s+1,s+1+strlen(s+1) ); T2.insert( s,1 );}T1.get_fail(); T2.get_fail();int now = 0, len = strlen( t+1 ), ans = 0;for(int i=1;i<=len;i++) { now = T2.zi[now][ft[i]-'a'];  ID[i] = now; }//保存反串的所有下标 now = 0;for(int i=1;i<=len-1;i++){now = T1.zi[now][t[i]-'a'];ans += T1.ok[now]*T2.ok[ID[len-i]];}cout << ans;
}

CF1202E You Are Given Some Strings...(ACAM正反串算贡献)相关推荐

  1. 习题归纳:KMP,ACAM的也许不是一句话题解

    正题 CF1200E Compress Words 直接将所有串的后缀自动机建出来,要找i和i+1的后前缀公共部分时,就将i+1的所有前缀打标记,用i来倍增找标记,标记可能要dfs序来维护,所以是两个 ...

  2. 工业机械人运动学正逆解,简单粗暴!!!!!!

    ur机械臂是六自由度机械臂,由D-H参数法确定它的运动学模型,连杆坐标系的建立如上图所示. 转动关节θi是关节变量,连杆偏移di是常数. 关节编号 α(绕x轴) a(沿x轴) θ(绕z轴) d(沿z轴 ...

  3. 2019金华正睿集训总结

    emmm-蒟蒻第一次出来集训,也是2019年noip(现在应该叫csp的说)前最后一次外出集训- 感觉压力好大啊-毕竟才学了不到一年啊- 但不管怎样,接下来几天要好好加油啊! DAY1 仅自己用的链接 ...

  4. 7.30 正睿暑期集训营 A班训练赛

    目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...

  5. 软件开发工期估算系列(1)——正確な見積もりはデスマーチ・プロジェクトを救うか?

    [转载按] 日本软件开发工期估算的系列文章,文中提出一个观点:"软件开发技术者的最高能力是--工期估算". 姑且不论这种观点是否正确,工期估算确实是项目开发中的一个比较大的难题, ...

  6. 【题单——基础字符串】菜鸡L_C_A的基础字符串(KMPACAM)

    洛谷题单 我是目录 P3375 [模板]KMP字符串匹配 CF1200E Compress Words P4824 USACO15FEB Censoring S P3435 [POI2006]OKR- ...

  7. ac自动机,自动ac机(bushi

    哈哈哈哈我学明白了也许吧.挂几篇题解: b站的这个up讲得太好啦:https://www.bilibili.com/video/BV1uJ411Y7Eg?p=3&vd_source=f5170 ...

  8. 三亚免税店积分抵现_又变了??三亚免税店的政策又变了~

    今年这是咋了,年中的时候三亚免税店搞了一波大变身 年底了又来一次大变身,这是瞄准了我的钱袋子啊 · 不扯了,直接说新变化 ⚠️会员积分变了,现在全品类消费30元,算1积分 ⚠️现在买化妆品不如以前那么 ...

  9. 总结 | 相机标定的基本原理与改进方法

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 学习3D视觉核心技术,扫描查看介绍,3天内无条件退款 圈里有高质量教程资料.可答疑解惑.助你高效解决问 ...

最新文章

  1. 基于 CODING 轻松搞定持续集成
  2. 隐式转换和显式转换及强制转换的区别
  3. nodejs系列(二)REPL交互解释 事件循环
  4. 第四十三节,文件、文件夹、压缩包、处理模块shutil
  5. Kafka 分布式环境搭建
  6. 《Web测试囧事》——1.3 测试Web Service能否正常提供JSON数据
  7. 天宫初级认证答案_百度初级认证考试题(附答案)
  8. 如何将 Ubuntu 配置为Ap模式
  9. 编辑器、编译器以及IDE
  10. PIC16F877A与Proteus仿真-1位7段数码管驱动
  11. 带目录计算机专业论文,计算机专业论文格式及目录系统
  12. jacob不能在Linux系统使用!
  13. AD 22 如何从SchDoc文件生成PcbDoc文件,进行布局和走线?
  14. A-4-YUM安装kubernetes
  15. accumulate详细用法
  16. android新特性:使用CollapsingToolbarLayout实现折叠效果及问题解决
  17. TinyOS论文11:Sentomist
  18. 小程序服务器域名和业务域名的总结和配置
  19. matlab中syms怎么替代,科学网—Matlab中的syms与conj - 孔令才的博文
  20. 21计算机考研408复习经验帖

热门文章

  1. 咱当爹的人, 有啥不一样
  2. Qt+Cmake+Opencv4.1.0环境搭建 directx文件错误
  3. 【西川善司】PLAYSTATION4图形讲座(前篇)
  4. 多个html合成txt,Python - 将多个HTML页解析为单个TXT文件
  5. Enyo 2 Onyx — LinuxTOY
  6. 操作系统之 动态分区分配与回收
  7. PS点击性能显示要求96和8之间的整数,已插入最接近的数值。
  8. 1M带宽支持多少人同时访问?网站带宽应该如何选择
  9. cf服务器优化,穿越火线地图编辑器来袭 服务器深度优化 网友:模仿我的世界?...
  10. Android屏幕刷新机制