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,长度分别 ...
随机推荐
- J07-Java IO流总结七 《 InputStreamReader和OutputStreamWriter 》
前面在介绍FileReader和FileWriter的时候有说到,FileReader的读取字符功能,以及FileWriter的写出字符的功能,都不是它们自己实现的,而是,它们分别继承了InputSt ...
- centos 7 nginx 安装
1.下载nginx rpm包 下载地址:http://nginx.org/packages/mainline/centos/7/x86_64/RPMS/ ,可查看所有安装包 从中如下载: wget h ...
- sublime text ubuntu
{ "color_scheme": "Packages/User/SublimeLinter/Dawn (SL).tmTheme", "font_fa ...
- SourceTree跳过Atlassian账号,免登陆,跳过初始设置
SourceTree 安装之后需要使用账号登陆以授权,并且是强制登陆. 登录过程非常漫长,并未在不FQ的情况下是不能成功的,下面记录一下跳过登录的方法. 装之后,转到用户本地文件夹下的 SourceT ...
- Android 开发工具类 05_Logcat 统一管理类
Logcat 统一管理类: 1.默 认tag 的函数: 2.自定义 tag 的函数. import android.util.Log; // Logcat 统一管理类 public class L { ...
- window启动程控制
1.启动服务管理(RPC) 2.开启远程选项 3.开启防火墙允许
- Chapter 3 Phenomenon——14
They wheeled me away then, to X-ray my head. 他们把我移到了一边用X光照射我的头. 他们把我放到轮椅上,推着我去做头部X光检查. I told them t ...
- pandas 去除NAN
df = df.dropna(axis=0, how='any')
- PHP-note
func_get_arg - Return an item from the argument list func_get_args - Returns an array comprising a f ...
- filebeat output redis 报错 i/o timeout
filebeat output redis 报错 i/o timeout 先把报错内容贴出来. ERROR redis/client. go: Failed to RPUSH to redis li ...