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

题解:CF291E Tree-String Problem

题意

给定一棵树,树的边上有字符串,字符串可以按照由父亲到儿子的方向拼接,求模式串 \(t\) 出现的次数。

思路

直接使用哈希。提前预处理出模式串 \(t\) 对应的哈希值,在搜索时计算当前点到儿子之间的边上的字符串对应的哈希值,并将其加入数组中,这样我们就得到了根节点到当前节点之间所有边上字符串拼接起来得到的长串的哈希值。计算答案的时候为了避免重复计算,只需要统计新加入的这一段(当前节点到儿子)上的每个字母为终点是否可以匹配。在回溯时记得更新长串的长度,减掉新加的字符串。

代码

#include<bits/stdc++.h>
#define int unsigned long long
#define MAXN 1000005
#define base 1331
using namespace std;
const int inf=1e18;
int n,m,cnt,head[MAXN],has[MAXN],len,hs,ans,p[MAXN];
string t;
struct Edge{int value,next;string s;
}edge[MAXN];
void addedge(int u,int v,string st){edge[++cnt].value=v;edge[cnt].next=head[u];edge[cnt].s=st;head[u]=cnt;
}
int fhas(int l,int r){return has[r]-has[l-1]*p[r-l+1];
}
void dfs(int x){for(int i=head[x];i;i=edge[i].next){int y=edge[i].value;string st=edge[i].s;for(int j=0;j<st.size();j++)has[len+j+1]=has[len+j]*base+st[j];for(int j=0;j<st.size();j++){if(len+j+1>=m){if(fhas(len+j-m+2,len+j+1)==hs)ans++;}}len+=st.size();dfs(y);len-=st.size();}
}
signed main(){p[0]=1;for(int i=1;i<=MAXN-5;i++)p[i]=p[i-1]*base;scanf("%lld",&n);for(int i=2;i<=n;i++){int x;string st;cin>>x>>st;addedge(x,i,st);}cin>>t;m=t.size();for(int i=1;i<=m;i++){has[i]=has[i-1]*base+t[i-1];}hs=has[m];dfs(1);printf("%lld\n",ans);return 0;
}

AC 记录

http://www.jsqmd.com/news/29387/

相关文章:

  • java操作sip
  • CH59X/CH58X蓝牙主机设置白名单
  • 题解:CF712D Memory and Scores
  • 思维的断章,觉知的永恒:一个基于“内观照叙事模型”的认知革命与跨学科范式重构
  • 拾壹月贰
  • struct page
  • NFS 服务端/客户端配置
  • CSP-S2025 题目解析
  • [Record] CSP-S 2025 邮寄
  • 2025 CSP-S 游记
  • [题解]CSP-S 2025 T1~T3 题解
  • 关于git关联github问题
  • AT ABC285E Work or Rest 题解
  • 代码复杂度的代价远比你想象得大
  • CSP2025 - S 年度总结大会报告
  • minio 服务端加密方式
  • 25CSP退役游记(11.1更新)
  • 第二章实践作业
  • (补11月)代码大全阅读笔记2
  • java 基础语法一
  • VisualStudio 2022如何打开.slnx文件格式的解决方案
  • (补11月)代码大全阅读笔记3
  • CSP2025 - S 游记
  • CSP-S游记
  • 小组作业1
  • C语言字符串及其函数
  • CPULOAD建模设计
  • C 文件操作全解速览
  • Java记录类:简化数据载体的新选择
  • 第二次算法作业