【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 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
随机推荐
- 开始 Dojo 开发
原文出处:Joe Lennon 从头开始学习 Dojo,第 1 部分 开始 Dojo 开发 Dojo Toolkit 简介 Dojo 于 2004 年创建,使开发 DHTML 和 JavaScript ...
- Java基础-字符串(String)常用方法
Java基础-字符串(String)常用方法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.java的API概念 Java的API(API:Application(应用) Pr ...
- Ubuntu下配置支持Windows访问的Samba共享
一.安装Ubuntu samba服务器 $ sudo apt-get install samba $ sudo apt-get install smbclient # Linux客户端测试用 二.创建 ...
- browser.versions.weixin
最近做很多HTML5的项目,很多页面会通过微信微博等SNS分享出去.在分享页面上提供公司APP的下载.但是在很多应用的浏览器中,点击下载链接无法下载应用.那么针对这些浏览器我们需要给用户提示从safa ...
- JDK各版本新特性总结
序言 北风潜入悄无声,未品浓秋已立冬. JDK1.1--1996 JDK1.2--1998 JDK1.3--2000 JDK1.4--2002 JDK5.0--2004 JDK6.0--2006 JD ...
- Elasticsearch技术解析与实战(五)Document解析
1.手动指定document id 一般来说,是从某些其他的系统中,导入一些数据到es时,会采取这种方式,就是使用系统中已有数据的唯一标识,作为es中document的id. PUT /index/t ...
- Python入门系列教程(三)列表和元组
增 1.insert A = ['] A.insert(0,0) print A 2.append A = ['] A.append(7) print A 3.extend A = ['] B = [ ...
- Web应用开发中的几个问题
Introduction 由于Ajax技术在Gmail中的成功应用和高性能的V8引擎的推出使得编写Web应用变得流行 起来,使用前端技术也可以编写具有复杂交互的应用.相对于native应用,Web应用 ...
- 小玩意1-实时获取IE浏览器输入框URL地址
主要参考http://www.cnblogs.com/scrat/archive/2012/09/12/2682626.html 主要思路如下: 通过 FindWindow() FindWindowE ...
- 在EF6.0中打印数据库操作日志
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...