@codefoces - 1313E@ Concatenation with intersection
@description@
给定两个长度为 n 的字符串 a, b 与一个长度为 m 的字符串 s。
问存在多少对区间 [l1, r1], [l2, r2](1 <= l1 <= r1 <= n, 1 <= l2 <= r2 <= n),使得:
1)两个区间含有交集。即存在 x 满足 l1 <= x <= r1 且 l2 <= x <= r2。
2)a[l1...r1] + b[l2...r2] = s。
@solution@
区间要有交集,可以等价认为是 l1 <= r2 且 l2 <= r1。
由题,区间长度和 (r1 - l1 + 1) + (r2 - l2 + 1) = m。
变形一下得到 (r2 - l1 + 1) + (r1 - l2 + 1) = m。
结合上面要有交集的不等式,可以得到 1 <= (r2 - l1 + 1) < m。
我们使用 z-algorithm 求出 a 中每一个 l1 与 s 的最长公共前缀,求出 b 中每一个 r2 与 s 的最长公共后缀。
接着,从后往前扫描 a 中的每一个 l1,维护 x[i] 表示如果 r1 - l1 + 1 = i 时对应了多少 r2。查询只需要区间求和即可。
因为 1 <= (r2 - l1 + 1) < m,得到 r2 的取值范围实际上是个滑动的区间。每一个 r2 的贡献是一个区间加。
因此直接用树状数组即可。
@accepted code@
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 500000;
const int MAXM = 2*MAXN;
int z[MAXM + MAXN + 5];
char str[MAXM + MAXN + 5];
void getZ(int len) {
int pos = 0, mxl = -1;
for(int i=1;i<len;i++) {
z[i] = (mxl >= i ? min(mxl - i + 1, z[i - pos]) : 0);
while( str[z[i]] == str[i+z[i]] ) z[i]++;
if( mxl < i + z[i] - 1 ) pos = i, mxl = i + z[i] - 1;
}
}
void get(char *S, int lenS, char *T, int lenT, int *f) {
for(int i=0;i<lenS;i++) str[i] = S[i];
str[lenS] = 1;
for(int i=0;i<lenT;i++) str[lenS+1+i] = T[i];
getZ(lenS + lenT + 1);
for(int i=0;i<lenT;i++) f[i] = z[lenS+1+i];
}
int n, m; ll T[2][MAXM + 5];
int lowbit(int x) {return (x & -x);}
void add(int x, ll d, int t) {
for(int i=x;i<=m;i+=lowbit(i))
T[t][i] += d;
}
void modify(int l, int r, ll d) {
add(l, d, 0), add(l, d*l, 1);
add(r + 1, -d, 0), add(r + 1, -d*(r + 1), 1);
}
ll sum(int x, int t) {
ll ret = 0;
for(int i=x;i;i-=lowbit(i))
ret += T[t][i];
return ret;
}
ll query(int l, int r) {
ll A = l*sum(l - 1, 0) - sum(l - 1, 1);
ll B = (r + 1)*sum(r, 0) - sum(r, 1);
return B - A;
}
char a[MAXN + 5], b[MAXN + 5], s[MAXM + 5];
int af[MAXN + 5], bf[MAXN + 5];
int main() {
scanf("%d%d%s%s%s", &n, &m, a, b, s);
get(s, m, a, n, af);
reverse(b, b + n), reverse(s, s + m);
get(s, m, b, n, bf);
reverse(bf, bf + n);
ll ans = 0;
for(int i=n-1;i>=0;i--) {
modify(max(m - bf[i], 1), m - 1, 1);
if( i + m - 1 < n )
modify(max(m - bf[i + m - 1], 1), m - 1, -1);
ans += query(1, af[i]);
}
printf("%lld\n", ans);
}
@details@
小清新的题目。
差点忘了树状数组的区间加与区间求和怎么写了。。。
@codefoces - 1313E@ Concatenation with intersection的更多相关文章
- [LeetCode] Intersection of Two Arrays II 两个数组相交之二
Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...
- [LeetCode] Intersection of Two Arrays 两个数组相交
Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...
- [LeetCode] Intersection of Two Linked Lists 求两个链表的交点
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- [LeetCode] Substring with Concatenation of All Words 串联所有单词的子串
You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...
- 【leetcode】Intersection of Two Linked Lists
题目简述: Write a program to find the node at which the intersection of two singly linked lists begins. ...
- [LintCode] Intersection of Two Linked Lists 求两个链表的交点
Write a program to find the node at which the intersection of two singly linked lists begins. Notice ...
- LeetCode Intersection of Two Arrays
原题链接在这里:https://leetcode.com/problems/intersection-of-two-arrays/ 题目: Given two arrays, write a func ...
- Leetcode Substring with Concatenation of All Words
You are given a string, S, and a list of words, L, that are all of the same length. Find all startin ...
- Intersection of Two Linked Lists
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
随机推荐
- ESlint中console.log报错问题
ESlint中console.log报错问题 由于ESlint规范化,导致console.log的使用也会报错,下面是设置允许console.log控制台输出 描述:打开 package.json 文 ...
- 解决iframe重定向让父级页面跳转
原文:http://www.jb51.net/article/40583.htm 有内嵌iframe的页面,当session过期时,点击连接重定向后的跳转会在iframe中跳转,在登录页面中加入下面的 ...
- WordPress 伪静态规则(IIS/Apache/Nginx)
不少朋友总是询问 WordPress 如何添加伪静态规则,今天倡萌就总结一下 Apache/Nginx 三种环境下的伪静态规则,希望对大家有所帮助. 检测主机是否支持伪静态的方法:在WP后台 > ...
- JSP+SSM+Mysql实现的图书馆预约占座管理系统
项目简介 项目来源于:https://gitee.com/gepanjiang/LibrarySeats 因原gitee仓库无数据库文件且存在水印,经过本人修改,现将该仓库重新上传至个人gitee仓库 ...
- 面试中很值得聊的二叉树遍历方法——Morris遍历
Morri遍历 通过利用空闲指针的方式,来节省空间.时间复杂度O(N),额外空间复杂度O(1).普通的非递归和递归方法的额外空间和树的高度有关,递归的过程涉及到系统压栈,非递归需要自己申请栈空间,都具 ...
- NO.1 MSP-ESP432P4111开箱
本人准备2020TI杯模拟电子邀请赛,预计参赛可能会使用TI平台,故从某宝购置一块MSP-ESP432P4111 LaunchPad为参赛做准备.TI官网40美刀,但我只能找国内二道贩子买,有点小贵& ...
- TopK (MinK) 实现
概述:基于快排原理找到最小的K个元素,属于Top K问题.注意,使用快排原理找前K小问题不需要对整个数组进行O(nlogn)的排序.我们只要找K所在的区间进行递归调用,即每次只要对数据的一半进行递归调 ...
- 读Pyqt4教程,带你入门Pyqt4 _003
编程中的一个重要事情是布局管理,布局管理是如何在窗体上摆放窗口组件.可以有两种方式进行管理:绝对定位或使用布局类. 绝对定位 程序员用像素指定每个控件的位置和尺寸.使用绝对定位时,你必须理解几件事情. ...
- AVIRIS 简介
AVIRIS 是指 机载可见光近红外成像光谱(Airborne Visible InfraRed Imaging Spectrometer).是由美国NASA下属的喷气动力实验室(JPL)开发和维护的 ...
- 03 . Redis集群
Redis集群方案 Redis Cluster 集群模式通常具有 高可用.可扩展性.分布式.容错等特性.Redis分布式方案一般有两种 客户端分区方案 客户端 就已经决定数据会被 存储到哪个 redi ...