NOIP 模拟 $25\; \rm string$
题解 \(by\;zj\varphi\)
考虑对于母串的每个字符,它在匹配串中有多少前缀,多少后缀。
设 \(f_i\) 表示 \(i\) 位置匹配上的前缀,\(g_i\) 为后缀,那么答案为 \(\sum_{i=1}^{len}f_i×g_i\)
那么如何求出 \(f_i\) 和 \(g_i\),考虑二分,求出一个最长的前缀,后缀。
在初始化时,将所有后缀记录上它的子后缀,前缀同理,用 \(trie\) 树就行,记得用 unordered_map
Code:
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf,OPUT[100];
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1<<21,1,stdin),p1==p2)?(-1):*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=0;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?x:-x;
}
template<typename T>inline void print(T x) {
if (x<0) putchar('-'),x=-x;
if (!x) return putchar('0'),(void)putchar('\n');
ri cnt(0);
while(x) OPUT[p(cnt)]=x%10,x/=10;
for (ri i(cnt);i;--i) putchar(OPUT[i]^48);
return (void)putchar('\n');
}
}
using IO::read;using IO::print;
namespace nanfeng{
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
typedef unsigned long long ull;
typedef long long ll;
static const int N=1e5+7,P=131,L=2e5+7;
int len1,len,n;
ll ans;
char s[N],s1[N];
ull p[N],h[N];
unordered_map<ull,int> mp1,mp2;
struct Trie{
#define Son(x,p) T[x].ch[p]
struct trie{int ch[26],nm;}T[L];
int tot;
Trie(){tot=1;}
inline void insert() {
ri cur=1;
for (ri i(1);i<=len;p(i)) {
ri ch=s[i]-'a';
if (!Son(cur,ch)) Son(cur,ch)=p(tot);
cur=Son(cur,ch);
p(T[cur].nm);
}
}
void dfs1(int nw,ull h) {
if (nw!=1&&T[nw].nm) mp1[h]=T[nw].nm;
for (ri i(0);i<26;p(i))
if (Son(nw,i)) {
T[Son(nw,i)].nm+=T[nw].nm;
dfs1(Son(nw,i),(ull)(i+1)+h*P);
}
}
void dfs2(int nw,ull h,int dep) {
if (nw!=1&&T[nw].nm) mp2[h]=T[nw].nm;
for (ri i(0);i<26;p(i))
if (Son(nw,i)) {
T[Son(nw,i)].nm+=T[nw].nm;
dfs2(Son(nw,i),(ull)(i+1)*p[dep]+h,dep+1);
}
}
}T1,T2;
inline int main() {
//FI=freopen("nanfeng.in","r",stdin);
//FO=freopen("nanfeng.out","w",stdout);
p[0]=1;
for (ri i(1);i<=N-7;p(i)) p[i]=p[i-1]*P;
scanf("%s",s1+1);
len1=strlen(s1+1);
for (ri i(1);i<=len1;p(i)) h[i]=h[i-1]*P+(ull)(s1[i]-'a'+1);
read(n);
ull k=-1;
for (ri i(1);i<=n;p(i)) {
scanf("%s",s+1);
len=strlen(s+1);
T1.insert();
reverse(s+1,s+len+1);
T2.insert();
}
T1.dfs1(1,0),T2.dfs2(1,0,0);
for (ri i(1);i<len1;p(i)) {
ri l(1),r(i),res(-1),tmp1(0),tmp2(0);
while(l<=r) {
int mid(l+r>>1);
if (mp2.find(h[i]-h[i-mid]*p[mid])!=mp2.end()) l=mid+1,res=mid;
else r=mid-1;
}
if (res!=-1) tmp2=mp2[h[i]-h[i-res]*p[res]];
l=1,r=len1-i,res=-1;
while(l<=r) {
int mid(l+r>>1);
if (mp1.find(h[i+mid]-h[i]*p[mid])!=mp1.end()) l=mid+1,res=mid;
else r=mid-1;
}
if (res!=-1) tmp1=mp1[h[i+res]-h[i]*p[res]];
ans+=1ll*tmp1*tmp2;
}
print(ans);
return 0;
}
}
int main() {return nanfeng::main();}
NOIP 模拟 $25\; \rm string$的更多相关文章
- NOIP 模拟 $25\; \rm random$
题解 \(by\;zj\varphi\) 期望好题. 通过推规律可以发现每个逆序对的贡献都是 \(1\),那么在所有排列中有多少逆序对,贡献就是多少. \[\rm num_i=(i-1)!\sum_{ ...
- NOIP 模拟 $25\; \rm queen$
题解 \(by\;zj\varphi\) 这是一道纯分类讨论,然后推式子的题,细节挺多,挺麻烦,但是很考验数学能力 不讲了,官方题解给的很清楚 Code: %: pragma GCC optimize ...
- 7.25 NOIP模拟8
这次考试前面状态还行,后两个小时真是一言难尽,打了个T3的n^2暴力就懵逼了,不知道怎么优化. T1.匹配 看了一边题发现不太懂(这不是考试的难度啊),然后水完T2后回来5分钟水过,非常愉快的一道题. ...
- NOIP模拟 1
NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. # 用 户 名 ...
- 2021.5.22 noip模拟1
这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...
- NOIP 模拟 $30\; \rm 毛一琛$
题解 \(by\;zj\varphi\) 如何判断一个集合可以被拆成两个相等的部分? 枚举两个集合,如果它们的和相等,那么他们的并集就是合法的,复杂度 \(\mathcal O\rm(3^n)\) \ ...
- NOIP模拟3
期望得分:30+90+100=220 实际得分:30+0+10=40 T1智障错误:n*m是n行m列,硬是做成了m行n列 T2智障错误:读入三个数写了两个%d T3智障错误:数值相同不代表是同一个数 ...
- 7.22 NOIP模拟7
又是炸掉的一次考试 T1.方程的解 本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判..暴力掉了40分. 首先a+b=c,只有一组解. 然后是a=1,b=1,答案是c-1 ...
- NOIP模拟 9
%liu_runda Orz T1 随 矩阵快速幂结合概率期望 但n3无法承受 利用原根的性质,将乘法转化成加法 就变成循环矩阵n^2了 改题时苦b地卡了关:误把1当成原根的1次方,错误地认为矩阵的阶 ...
随机推荐
- fast-poster海报生成器v1.4.0,一分钟完成海报开发
fast-poster海报生成器v1.4.0,一分钟完成海报开发 介绍 一个快速开发动态海报的工具 在线体验:https://poster.prodapi.cn/ v1.4.0 新特性 为了项目和团队 ...
- Nacos实战一:架构及部署
2018年,阿里巴巴开源 Nacos,由此成为继 Eureka.Consul.Apollo 等服务注册发现&配置的又一开源框架,到如今2021年,Nacos 已经历了 0.01->1.4 ...
- ARTS第十三周(阅读Tomcat源码)
1.Algorithm:每周至少做一个 leetcode 的算法题2.Review:阅读并点评至少一篇英文技术文章3.Tip:学习至少一个技术技巧4.Share:分享一篇有观点和思考的技术文章 考研真 ...
- 题解 guP1948 【[USACO08JAN]电话线Telephone Lines】
二分+dij题目 首先读一遍题目,一定要仔细读(不要问我为什么,我就是受害者qwq 你会发现最终的费用是由最长的电话线决定的,而非电话线长度和. 至此就有了一个基本思路--枚举(二分)出可能的最长电话 ...
- ARC 122 简要题解
ARC 122 简要题解 传送门 A - Many Formulae 考虑对于每个数分别算其贡献. 通过枚举该数前面的符号,借助一个非常简单的 \(\mathrm{DP}\)(\(f_{i,0/1}\ ...
- 从新建文件夹开始构建ShadowPlay Engine游戏引擎(3)
本篇序言 各位可能看到博文的名字换了,也就是引擎名字换了,其实是在下想到了一个更棒的名字:皮影戏(ShadowPlay),取这个名字的含义是因为,游戏中的角色(Puppet)不也是由于我们的操作而动起 ...
- C语言:最小公倍数
//求最小公倍数 #include <stdio.h> main() { int m,n,i,k,max,min; scanf("%d,%d",&m,& ...
- 实验4 RDD编程初级实践
1.spark-shell交互式编程 (1) 该系总共有多少学生 scala> val lines = sc.textFile("file:///usr/local/spark/spa ...
- Python+Request库+第三方平台实现验证码识别示例
1.登录时经常的出现验证码,此次结合Python+Request+第三方验证码识别平台(超级鹰识别平台) 2.首先到超级鹰平台下载对应语言的识别码封装,超级鹰平台:http://www.chaojiy ...
- 【C#】C#中使用GDAL3(二):Windows下读写Shape文件及超详细解决中文乱码问题
转载请注明原文地址:https://www.cnblogs.com/litou/p/15035790.html 本文为<C#中使用GDAL3>的第二篇,总目录地址:https://www. ...