[HAOI 2016]找相同字符
Description
给定两个只含小写字母字符串 \(s_1,s_2\) ,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两个子串中有一个位置不同。
\(1\leq |s_1|,|s_2|\leq 200000\)
Solution
把两个串拼在一起,然后扫两遍。
第一遍统计所有的 \(B\) ,在它前面的 \(A\) 的贡献;第二遍统计所有的 \(A\) ,在它前面的 \(B\) 的贡献;
用单调栈维护一下即可。
Code
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = (200000+5)<<1;
char ch[N];
int s1, n, m, x[N<<1], y[N<<1], c[N], sa[N], rk[N], height[N];
ll ans, sum[N], a[N];
int s[N], top;
void get() {
for (int i = 1; i <= n; i++) c[x[i] = ch[i]]++;
for (int i = 2; i <= m; i++) c[i] += c[i-1];
for (int i = n; i >= 1; i--) sa[c[x[i]]--] = i;
for (int k = 1; k <= n; k <<= 1) {
int num = 0;
for (int i = n-k+1; i <= n; i++) y[++num] = i;
for (int i = 1; i <= n; i++) if (sa[i] > k) y[++num] = sa[i]-k;
for (int i = 1; i <= m; i++) c[i] = 0;
for (int i = 1; i <= n; i++) c[x[i]]++;
for (int i = 2; i <= m; i++) c[i] += c[i-1];
for (int i = n; i >= 1; i--) sa[c[x[y[i]]]--] = y[i];
swap(x, y); x[sa[1]] = num = 1;
for (int i = 2; i <= n; i++)
x[sa[i]] = (y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k]) ? num : ++num;
if ((m = num) == n) break;
}
for (int i = 1; i <= n; i++) rk[sa[i]] = i;
for (int i = 1, k = 0; i <= n; i++) {
if (rk[i] == 0) continue;
if (k) k--; int j = sa[rk[i]-1];
while (i+k <= n && j+k <= n && ch[i+k] == ch[j+k]) ++k;
height[rk[i]] = k;
}
}
void cal(int ss) {
top = 0;
for (int i = 1; i <= n; i++) sum[i] = sum[i-1]+(ss == (sa[i] > s1) && sa[i] != s1+1);
for (int i = 1; i <= n; i++) {
while (top && height[s[top]] >= height[i]) --top;
s[++top] = i; a[top] = a[top-1]+(sum[i-1]-sum[s[top-1]-1])*height[i];
if (ss == (sa[i] <= s1) && sa[i] != s1+1) ans += a[top];
}
}
void work() {
scanf("%s", ch+1); s1 = strlen(ch+1);
ch[s1+1] = '$'; scanf("%s", ch+s1+2);
n = strlen(ch+1); m = 255; get();
cal(0), cal(1); printf("%lld\n", ans);
}
int main() {work(); return 0; }
[HAOI 2016]找相同字符的更多相关文章
- [bzoj 4566][Haoi 2016]找相同字符
传送门 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Solution 考虑用SAM,采用较为轻 ...
- BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机)
BZOJ4566&&lg3181 HAOI找相同字符(广义后缀自动机) 题面 自己找去 HINT 给定两个文本串,问从两个串中各取一个非空子串,使这俩子串相同,问方案有多少种.我的思路 ...
- BZOJ 4566: [Haoi2016]找相同字符 [后缀自动机]
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 275 Solved: 155[Submit][Statu ...
- 【BZOJ4566】找相同字符(后缀数组)
[BZOJ4566]找相同字符(后缀数组) 题面 BZOJ 题解 后缀数组的做法,应该不是很难想 首先看到两个不同的串,当然是接在一起求\(SA,height\) 那么,考虑一下暴力 在两个串各枚举一 ...
- 【BZOJ4566】找相同字符(后缀自动机)
[BZOJ4566]找相同字符(后缀自动机) 题面 BZOJ 题解 看到多串处理,\(SA\)就连起来 \(SAM???\) 单串建自动机 然后其他串匹配 对于一个串建完\(SAM\)后 另一个串在\ ...
- bzoj4566 / P3181 [HAOI2016]找相同字符
P3181 [HAOI2016]找相同字符 后缀自动机 (正解应是广义后缀自动机) 并不会广义后缀自动机. 然鹅可以用普通的后缀自动机. 我们先引入一个问题:算出从一个串内取任意两个不重合子串完全 ...
- 【BZOJ4566】[HAOI2016]找相同字符
[BZOJ4566][HAOI2016]找相同字符 题面 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. 其中\(1\le ...
- [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1212 Solved: 694[Submit][Stat ...
- 【BZOJ4566】[Haoi2016]找相同字符 后缀数组+单调栈
[BZOJ4566][Haoi2016]找相同字符 Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同 ...
随机推荐
- oracle 区分大小写遇到的坑
1. oracle 字段是区分大小写的 ..在navicat 中使用查询 select REMAIN_PRINCIPAl from T_NF_PROJECT; navicat 默认会把 REMA ...
- idea执行mapreduce报错 Could not locate Hadoop executable: C:\hadoop-3.1.1\bin\winutils.exe
window执行mapreduce报错 Exception in thread "main" java.lang.RuntimeException: java.io.FileNot ...
- c++WIN32获取syslistview行数
#include "stdafx.h" #include <windows.h> #include <commctrl.h> #include <io ...
- JavaWeb环境搭建(作业八)
1.JDK下载配置: (1)在官网下载jdk. (2)安装jdk.双击下载好的jdk,中间会选两次安装路径,一次是装jdk,一次是装jre.记住安装的路径. (3)配置环境变量. 1.在我的电脑右键属 ...
- 20155326《网络攻防》Exp4 恶意代码分析
20155326<网络攻防>Exp4 恶意代码分析 基础问题回答: 1)如果在工作中怀疑一台主机上有恶意代码,但只是猜想,所有想监控下系统一天天的到底在干些什么.请设计下你想监控的操作有哪 ...
- SQL Server CTE 递归查询全解 -- 转 学习
在TSQL脚本中,也能实现递归查询,SQL Server提供CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询,本文详细介绍CTE递归调用的特性和使用示例 ...
- IntelliJ IDEA的破解方法
一.下载并安装, IntelliJ IDEA的官网:https://www.jetbrains.com 下载 下载 下载 二.破解. 百度下载一个 JetbrainsCrack-2.7-release ...
- windows基于vs2017的opencv安装
1.opencv下载与安装 1.下载地址:官网下载地址https://opencv.org/releases.html opencv为开源软件,可直接在官网下载最新版本. 2.软件安装:openc ...
- MFC开发中添加自定义消息和消息响应函数
(1)在.h或.cpp文件定义一个消息 #define CLICK_MESSAGE_BOX WM_USER+1001 //add by 20180612 给主窗口ctrl.cpp发送消息 //自定义消 ...
- 循环结构-for,while,do-while
for,while,do-while >完整的循环应该包含以下四个部分: 初始化语句:初始化工作,在循环体开始之前执行 条件表达式:一个boolean表达式,决定是否执行循环体 循环体:反复执行 ...