传送门

这题思路太清奇了……->题解

 //minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getchar()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getchar());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
const int N=1e5+;
char str[N],s[N];
ll ans=;
int ver[N],Next[N],head[N],tot=;
int sqr,id1[N],id2[N];
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
int vis[N],rt,son[N],sz[N],size,n,m;
struct SAM{
int rt,last,tot,ch[N][],fa[N],l[N],cnt[N];
int s[N],tag[N],son[N][],le[N];
SAM(){rt=last=tot=;}
int ins(int c){
int p=last,np=++tot;last=np,le[np]=l[np]=l[p]+,cnt[np]=;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=rt;
else{
int q=ch[p][c];
if(l[q]==l[p]+) fa[np]=q;
else{
int nq=++tot;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
l[nq]=l[p]+,le[nq]=le[q];
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for(;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
return last;
}
int a[N],c[N];
void calc(){
for(int i=;i<=tot;++i) ++c[l[i]];
for(int i=;i<=tot;++i) c[i]+=c[i-];
for(int i=tot;i;--i) a[c[l[i]]--]=i;
for(int i=tot,p;i>=;--i){
p=a[i];
cnt[fa[p]]+=cnt[p];
son[fa[p]][s[le[p]-l[fa[p]]]]=p;
}
}
void mark(int u,int fa,int now,int len){
if(!now) return;
if(len==l[now]) now=son[now][str[u]-'a'];
else if(s[le[now]-len]!=str[u]-'a') now=;
if(!now) return;
++tag[now];
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa&&!vis[v]) mark(v,u,now,len+);
}
}
inline void push(){for(int i=;i<=tot;++i) tag[a[i]]+=tag[fa[a[i]]];}
}sam1,sam2;
void findrt(int u,int fa){
sz[u]=,son[u]=;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa&&!vis[v])
findrt(v,u),sz[u]+=sz[v],cmax(son[u],sz[v]);
}
cmax(son[u],size-sz[u]);
if(!rt||son[u]<son[rt]) rt=u;
}
int num=,g[N];
void get(int u,int fa){
g[++num]=u;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa&&!vis[v]) get(v,u);
}
}
void getsum(int u,int fa){
++size;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa&&!vis[v]) getsum(v,u);
}
}
void dfs(int u,int fa,int now){
now=sam1.ch[now][str[u]-'a'];
if(!now) return;
ans+=sam1.cnt[now];
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa&&!vis[v]) dfs(v,u,now);
}
}
void work(int u,int fa,int op){
for(int i=;i<=sam1.tot;++i) sam1.tag[i]=;
for(int i=;i<=sam2.tot;++i) sam2.tag[i]=;
int to=str[fa]-'a';
if(fa) sam1.mark(u,fa,sam1.son[][to],),sam2.mark(u,fa,sam2.son[][to],);
else sam1.mark(u,fa,,),sam2.mark(u,fa,,);
sam1.push(),sam2.push();
for(int i=;i<=m;++i) ans+=1ll*op*sam1.tag[id1[i]]*sam2.tag[id2[m-i+]];
}
void solve(int u){
if(size<=sqr){
num=,get(u,);
for(int i=;i<=num;++i) dfs(g[i],,sam1.rt);
return;
}
vis[u]=,work(u,,);
for(int i=head[u];i;i=Next[i])
if(!vis[ver[i]]) work(ver[i],u,-);
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(vis[v]) continue;
size=,getsum(v,u);
rt=,findrt(v,u);
solve(rt);
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=,u,v;i<n;++i)
u=read(),v=read(),add(u,v),add(v,u);
scanf("%s",str+),scanf("%s",s+);
for(int i=;i<=m;++i) sam1.s[i]=s[i]-'a',id1[i]=sam1.ins(s[i]-'a');
reverse(s+,s++m);
for(int i=;i<=m;++i) sam2.s[i]=s[i]-'a',id2[i]=sam2.ins(s[i]-'a');
sam1.calc(),sam2.calc();
rt=,son[]=n+,size=n,sqr=sqrt(n);
findrt(,),solve(rt);
printf("%lld\n",ans);
return ;
}

洛谷P4218 [CTSC2010]珠宝商(后缀自动机+点分治)的更多相关文章

  1. 洛谷P4248 [AHOI2013]差异(后缀自动机求lcp之和)

    题目见此 题解:首先所有后缀都在最后一个np节点,然后他们都是从1号点出发沿一些字符边到达这个点的,所以下文称1号点为根节点,我们思考一下什么时候会产生lcp,显然是当他们从根节点开始一直跳相同节点的 ...

  2. P4218 [CTSC2010]珠宝商

    P4218 [CTSC2010]珠宝商 神题... 可以想到点分治,细节不写了... (学了个新姿势,sam可以在前面加字符 但是一次点分治只能做到\(O(m)\),考虑\(\sqrt n\)点分治, ...

  3. 洛谷-P5357-【模板】AC自动机(二次加强版)

    题目传送门 -------------------------------------- 过年在家无聊补一下这周做的几道AC自动机的模板题 sol:AC自动机,还是要解决跳fail边产生的重复访问,但 ...

  4. [BJWC2018]Border 的四种求法(后缀自动机+链分治+线段树合并)

    题目描述 给一个小写字母字符串 S ,q 次询问每次给出 l,r ,求 s[l..r] 的 Border . Border: 对于给定的串 s ,最大的 i 使得 s[1..i] = s[|s|-i+ ...

  5. 洛谷P1393 动态逆序对(CDQ分治)

    传送门 题解 听别人说这是洛谷用户的双倍经验啊……然而根本没有感觉到……因为另外的那题我是用树状数组套主席树做的……而且莫名其妙感觉那种方法思路更清晰(虽然码量稍稍大了那么一点点)……感谢Candy大 ...

  6. Bzoj2152/洛谷P2634 聪聪可可(点分治)

    题面 Bzoj 洛谷 题解 点分治套路走一波,考虑\(calc\)函数怎么写,存一下每条路径在\(\%3\)意义下的路径总数,假设为\(tot[i]\)即\(\equiv i(mod\ 3)\),这时 ...

  7. 洛谷 P6199 - [EER1]河童重工(点分治+虚树)

    洛谷题面传送门 神仙题. 首先看到这样两棵树的题目,我们肯定会往动态树分治的方向考虑.考虑每次找出 \(T_2\) 的重心进行点分治.然后考虑跨过分治中心的点对之间的连边情况.由于连边边权与两棵树都有 ...

  8. 洛谷P3966 [TJOI2013]单词(AC自动机)

    题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...

  9. 洛谷P2444 病毒【AC自动机】

    题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...

随机推荐

  1. 项目log4j日志管理详解

    项目log4j日志管理详解 log4j日志系统在项目中重要性在这里就不再累述,我们在平时使用时如果没有特定要求,只需在log4j.properties文件中顶入输出级别就行了.如果要自定义输出文件,对 ...

  2. cygwin添加到有右键菜单

    cygwin添加到有右键菜单 前提 为了在windows中使用cygwin编译指定文件代码更为方便,所以动心思琢磨把cygwin添加到右键菜单,百度了一下,发现很多这样的教程,但是有问题,比如添加了但 ...

  3. Android程序-计算器

    基于Android 2.3.3做的一个练手计算器. 可解析带括号的四则运算. 解析算术表达式的时候,准备调用Webkit通过Js来解析的. 但是2.3.3存在Bug,Js调用Java会导致程序崩溃,  ...

  4. Android窗口系统第三篇---WindowManagerService中窗口的组织方式

    Android窗口系统第一篇—Window的类型与Z-Order确定 Android窗口系统第二篇—Window的添加过程 上面文章梳理了一个窗口的添加过程,系统中有很多应用,每个应用有多个Activ ...

  5. python 3 - 写一个注册的程序,账号和密码都存在文件里面

    choice = input('请输入你的选择:1,注册2.删除用户3.登录') #注册 输入 账号 密码 密码确认 # #需要校验用户是否存在,两次输入的密码,是否一致,为空的情况 #账号和密码都存 ...

  6. form 提交数据编码梳理

    之前对form单提交的操作一直都是迷迷糊糊,知道怎么用,但是随着ajax2的出现,我们有更多的方式操作form表单提交,但是底层的原理我们要好好的做个梳理. 常见的form提交有post和get这两种 ...

  7. Python: Neural Networks

    这是用Python实现的Neural Networks, 基于Python 2.7.9, numpy, matplotlib. 代码来源于斯坦福大学的课程: http://cs231n.github. ...

  8. AtCoder Beginner Contest 103

    https://beta.atcoder.jp/contests/abc103 A - Task Scheduling Problem Time Limit: 2 sec / Memory Limit ...

  9. 【LeetCode】046. Permutations

    题目: Given a collection of distinct numbers, return all possible permutations. For example,[1,2,3] ha ...

  10. 1130 host is not allowed to connect to

    mysql 远程访问不行解决方法 Host is not allowed to connect to this MySQL server 如果你想连接你的mysql的时候发生这个错误: ERROR 1 ...