【LOJ】#2064. 「HAOI2016」找相同字符
题解
做后缀自动机题要一点脑洞,脑洞一开,就过了
我们显然要拿第二个串跑第一个串的后缀自动机
我们可以求出第二个串每个位置匹配到的节点,和匹配的长度L
那么我们统计一个后缀树上的根缀和,表示这样个节点的路径字符串的所有后缀在串中出现过多少次(路径字符串就是根到这个点的路径中等于这个节点len值的串)
统计方法是p->sum = p->par->sum + p->cnt * (p->len - p->par->len)
然后我们匹配到的位置不一定完整匹配了路径字符串,所以我们第二个串某个位置能匹配到的串的个数是
p->par->sum + p->cnt * (L - p->par->len)
代码
#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define MAXN 200005
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
struct node {
node *nxt[26],*par;
int len,cnt;
int64 sum;
}pool[MAXN * 2],*tail = pool,*root,*last,*que[MAXN * 2];
char s1[MAXN],s2[MAXN];
int N1,N2,c[MAXN];
void build_sam(int l,int c) {
node *nowp = tail++,*p;
nowp->len = l;nowp->cnt = 1;
for(p = last ; p && !p->nxt[c] ; p = p->par) {
p->nxt[c] = nowp;
}
if(!p) nowp->par = root;
else {
node *q = p->nxt[c];
if(q->len == p->len + 1) nowp->par = q;
else {
node *copyq = tail++;
*copyq = *q;
copyq->len = p->len + 1;copyq->cnt = 0;
q->par = nowp->par = copyq;
for(; p && p->nxt[c] == q ; p = p->par) {
p->nxt[c] = copyq;
}
}
}
last = nowp;
}
void Solve() {
scanf("%s",s1 + 1);
scanf("%s",s2 + 1);
N1 = strlen(s1 + 1);N2 = strlen(s2 + 1);
root = last = tail++;
for(int i = 1 ; i <= N1 ; ++i) build_sam(i,s1[i] - 'a');
int m = tail - pool;
for(int i = 0 ; i < m ; ++i) c[pool[i].len]++;
for(int i = 1 ; i <= N1 ; ++i) c[i] += c[i - 1];
for(int i = 0 ; i < m ; ++i) que[c[pool[i].len]--] = &pool[i];
for(int i = m ; i >= 1 ; --i) {
if(que[i]->par) que[i]->par->cnt += que[i]->cnt;
}
for(int i = 2 ; i <= m ; ++i) {
que[i]->sum = que[i]->par->sum + 1LL * (que[i]->len - que[i]->par->len) * que[i]->cnt;
}
int l = 0;
node *p = root;
int64 ans = 0;
for(int i = 1 ; i <= N2 ; ++i) {
int a = s2[i] - 'a';
if(p->nxt[s2[i] - 'a']) {p = p->nxt[a];++l;}
else {
while(p->par && !p->nxt[a]) p = p->par;
if(p->nxt[a]) {l = p->len + 1;p = p->nxt[a];}
else {l = 0;}
}
if(p != root) ans += p->par->sum + 1LL * (l - p->par->len) * p->cnt;
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}
哦这道题看起来是比NOI2018D1T3的68分难一点的
但是我都是半个小时以内想出来了
真讽刺
【LOJ】#2064. 「HAOI2016」找相同字符的更多相关文章
- 「HAOI2016」找相同字符
知识点: SA,线段树,广义 SAM 原题面 Loj Luogu 给定两字符串 \(S_1, S_2\),求出在两字符串中各取一个子串,使得这两个子串相同的方案数. 两方案不同当且仅当这两个子串中有一 ...
- 「HAOI2016」字符合并
「HAOI2016」字符合并 题意: 有一个长度为\(n\)的\(01\)串,你可以每次将相邻的\(k\)个字符合并,得到一个新的字符并获得一定分数.得到的新字符和分数由这\(k\)个字符确定.你 ...
- Loj #3057. 「HNOI2019」校园旅行
Loj #3057. 「HNOI2019」校园旅行 某学校的每个建筑都有一个独特的编号.一天你在校园里无聊,决定在校园内随意地漫步. 你已经在校园里呆过一段时间,对校园内每个建筑的编号非常熟悉,于是你 ...
- Loj #3059. 「HNOI2019」序列
Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...
- Loj #3055. 「HNOI2019」JOJO
Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...
- loj#2552. 「CTSC2018」假面
题目链接 loj#2552. 「CTSC2018」假面 题解 本题严谨的证明了我菜的本质 对于砍人的操作好做找龙哥就好了,blood很少,每次暴力维护一下 对于操作1 设\(a_i\)为第i个人存活的 ...
- Loj #3042. 「ZJOI2019」麻将
Loj #3042. 「ZJOI2019」麻将 题目描述 九条可怜是一个热爱打麻将的女孩子.因此她出了一道和麻将相关的题目,希望这题不会让你对麻将的热爱消失殆尽. 今天,可怜想要打麻将,但是她的朋友们 ...
- Loj #2529. 「ZJOI2018」胖
Loj #2529. 「ZJOI2018」胖 题目描述 Cedyks 是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks 是一个富有的男孩子.他住在著名的 The P ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
随机推荐
- 有关并查集的emmmm
并查集 顾名思义,并查集有三个用处 并,即合并两个集合 查,查询该元素所在的集合 集,就指集合 现在来说一说并查集的基本操作: - 初始化 首先,最开始的时候,我们假设所有的集合都只有一个元素,即只有 ...
- spring-mvc Mybatis插件打印SQL
代码: package com.chainup.exchange.service.adapter; import com.chainup.exchange.service.impl.AccountSe ...
- 计算广告学-多点归因模型(Multi-Touch Attribution Model)
计算广告学中的一个重要的问题是, 如果用户产生了一次转化(conversion, 比如购买, 注册等), 且该用户在转化之前看过大量不同频道(比如搜索, 展示, 社交等等)的广告, 那么我们如何确定是 ...
- 对一道pwnhub的一点点记录
一.通过ssh弱口令,建立socket5代理进内网. 1.修改proxychains配置文件vi /etc/proxychains.conf如下: 2.建立ssh隧道:ssh -qTfnN -D 70 ...
- 42、Java装饰者设计模式
设计模式简介 什么是设计模式?设计模式是可以重复利用的解决方案.软件开发的先驱或者前辈们将之前在开发中遇到的问题进行总结并给出了解决方案,后辈在遇到这些问题之后直接使用这些方案即可解决问题.比如盖高楼 ...
- 正在载入中......loading页面的几种方法
网页加载过程中提示“载入中…”,特别是使用动画效果,可以一个“等待”的温馨提示,用户体验很不错.下面介绍几种方法. 第一种: 原理就是,在网页载入时在页面最中间打入一个层上面显示,"网页正在 ...
- 初涉sqlmap
1.基本注入(这个工具kali或者bt下面有集成的,这里附加一个window免py版,提取码:3ldv) sqlmap -u http://url/xx.php?id=1 判断注入 sqlmap - ...
- 【Tomcat】Tomcat容器 web.xml详解
Tomcat的安装目录下的conf目录下的web.xml文件有许多配置,例如: <init-param> <param-name>debug</param-name& ...
- 解决Win7&Win8 64位下Source Insight提示未完整安装的问题[转]
转自:http://www.cnblogs.com/sixiweb/p/3421533.html 网上的破解版的注册表文件都是针对32位系统的,所以在64位系统里运行根本无法破解.下面分别贴出这俩系统 ...
- 『实践』百度地图给map添加右键菜单(判断是否为marker)
var map; var s;//经度 var w;//纬度 $(document).ready(function(){ $(".mune").load("jsp/c ...