BZOJ4566: [Haoi2016]找相同字符(后缀自动机)
题意
Sol
直接在SAM上乱搞
枚举前缀,用SAM统计可以匹配的后缀,具体在匹配的时候维护和当前节点能匹配的最大值
然后再把parent树上的点的贡献也统计上,这部分可以爆跳parent树(假的,因为这题数据随机),也可以直接树形dp一波记下每个点被统计的次数
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 4e5 + 10;
int N1, N2;
char a[MAXN], b[MAXN];
// struct SAM {
int fa[MAXN], ch[MAXN][26], len[MAXN], siz[MAXN], tot, las, root, f[MAXN], g[MAXN];
vector<int> v[MAXN];
// SAM() {
// root = las = tot = 1;
// }
void insert(int x) {
int now = ++tot, pre = las; las = now; siz[now] = 1;
len[now] = len[pre] + 1;
for(; pre && !ch[pre][x]; pre = fa[pre]) ch[pre][x] = now;
if(!pre) fa[now] = root;
else {
int q = ch[pre][x];
if(len[pre] + 1 == len[q]) fa[now] = q;
else {
int ns = ++tot; fa[ns] = fa[q]; len[ns] = len[pre] + 1;
memcpy(ch[ns], ch[q], sizeof(ch[q]));
fa[q] = fa[now] = ns;
for(; pre && ch[pre][x] == q; pre = fa[pre]) ch[pre][x] = ns;
}
}
}
void Build() {
for(int i = 2; i <= tot; i++) v[fa[i]].push_back(i);
}
void dfs(int x, int opt) {
for(int i = 0; i < v[x].size(); i++) {
int to = v[x][i];
dfs(to, opt);
if(opt == 1) siz[x] += siz[to];
if(opt == 2) f[x] += f[to] + g[to];
}
}
// }sam;
int main() {
root = las = tot = 1;
scanf("%s%s", a + 1, b + 1);
N1 = strlen(a + 1); N2 = strlen(b + 1);
for(int i = 1; i <= N1; i++) insert(a[i] - 'a');
Build(); dfs(root, 1);
int now = root, cur = 0; LL ans = 0;
for(int i = 1; i <= N2; i++) {
int x = b[i] - 'a';
if(ch[now][x]) now = ch[now][x], cur++;
else {
while(!ch[now][x] && now) now = fa[now];
if(!now) now = 1, cur = 0;
else cur = len[now] + 1, now = ch[now][x];
}
ans += 1ll * (cur - len[fa[now]]) * siz[now];
g[now]++;
//int tmp = fa[now];
//while(tmp != 1) ans += (len[tmp] - len[fa[tmp]]) * siz[tmp], tmp = fa[tmp];
}
dfs(root, 2);
for(int i = 1; i <= tot; i++) ans += 1ll * (len[i] - len[fa[i]]) * siz[i] * f[i];
cout << ans;
return 0;
}
/*
aa
aa
acb
abc
ababababba
abbababab
*/
BZOJ4566: [Haoi2016]找相同字符(后缀自动机)的更多相关文章
- [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1212 Solved: 694[Submit][Stat ...
- BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 275 Solved: 155[Submit][Statu ...
- HAOI2016 找相同字符 后缀自动机
两个串,考虑一建一跑.枚举模式串的位置\(i\),考虑每次统计以\(i\)结尾的所有符合要求的串.在后缀自动机上走时记录当前匹配长度\(curlen\),则当前节点的贡献是\((curlen-len[ ...
- BZOJ4566 [Haoi2016]找相同字符【SAM】
BZOJ4566 [Haoi2016]找相同字符 给定两个字符串\(s和t\),要求找出两个字符串中所有可以相互匹配的子串对的数量 首先考虑可以怎么做,我们可以枚举\(t\)串的前缀\(t'\),然后 ...
- [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 861 Solved: 495[Submit][Statu ...
- 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈
[BZOJ4566][Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...
- [HAOI2016] 找相同字符 - 后缀数组,单调栈
[HAOI2016] 找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. \(n,m \l ...
- BZOJ4566 Haoi2016 找相同字符【广义后缀自动机】
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- BZOJ4566: [Haoi2016]找相同字符
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
随机推荐
- 使用VS Code开发.Net Core 2.0 MVC Web应用程序教程之三(配置文件读取)
干了一天的活,还有点时间,给兄弟们写点东西吧. 大家有没有发现一个问题?那就是在.Net Core的MVC项目里面,没有.config文件了!!!同志们,没有config文件了啊,这样搞,我以后要做些 ...
- webpack快速入门——配置文件:入口和出口,多入口、多出口配置
1.在根目录新建一个webpack.config.js文件,然后开始配置: const path = require('path'); module.exports={ //入口文件的配置项 entr ...
- ubuntu14.0 安装 node v8.11.1(任意版本)
由于众所周知的原因,通过node官网下载速度十分慢,我这里通过淘宝镜像安装 node8.11.1,其他版本同理. node版本淘宝镜像地址:https://npm.taobao.org/mirrors ...
- [Swift实际操作]七、常见概念-(7)日历Calendar和日期组件DateComponents
本文将为你演示日历和日期组件的使用.通过日历的日期部件,可以获得日期的各个部分. 首先引入需要用到的界面工具框架 import UIKit 初始化一个日期对象,其值为当前的日期. let dt = D ...
- iOS开发总结--三方平台开发之分享
1.前言 在公司参与了多个应用三方平台的开发,涉及微信.微博.QQ.Facebook.meetup等,总结一下一般的接入三方平台SDK方法. 2.接入三方SDK 任何应用要接入三方平台,都需要在该平台 ...
- (原创)定时线程池中scheduleWithFixedDelay和scheduleAtFixedRate的区别
scheduleAtFixedRate 没有什么歧义,很容易理解,就是每隔多少时间,固定执行任务. scheduleWithFixedDelay 比较容易有歧义 貌似也是推迟一段时间执行任务,但Ora ...
- js实现仿华为手机计算器,兼容电脑和手机屏幕
效果图: 电脑端: 手机端: 源码: <!DOCTYPE html> <html lang="en"> <head> <meta char ...
- 剑指offer二十二之从上往下打印二叉树
一.题目 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 二.思路 二叉树的层次遍历,可以借助队列实现.具体思路详见注释. 三.代码 import java.util.ArrayList; i ...
- Android Studio启动速度慢的问题。
Android Studio每次启动都要去fetching sdk,由于Android sdk 官网在大陆连不上,所以每次启动时界面都会停在那里很久. 要提高启动速度,就要避免每次启动Android ...
- R语言之数据处理常用包
dplyr包是Hadley Wickham的新作,主要用于数据清洗和整理,该包专注dataframe数据格式,从而大幅提高了数据处理速度,并且提供了与其它数据库的接口:tidyr包的作者是Hadley ...