/*
HDU 6068 - Classic Quotation [ KMP,DP ] | 2017 Multi-University Training Contest 4
题意:
给出两个字符串 S[N], T[M], k个询问
每个询问给出 L,R
对所有 1<=i<=L , r<=j<=N ,
S串拿掉[i+1,j-1]的子串后,剩下两个子串拼在一起的子串中 T 串的数目求和
限制 N,k <= 5e4, M <= 100
分析:
pre[i] 代表 前缀i匹配的T的数目
num[i][j] = 1 代表 前缀i,失配位置为 j
将 pre[i], num[i][j] 求前缀和
suf[i][j] 代表 后缀i,从T[j]开始匹配上的T的数目
ans = pre[L] * (n-R+1) + ∑_[1<=i<=m] num[l][i] * suf[R][i]
所以对于每个询问可 O(m) 时间内求出 pre[i], num[i][j] 可 KMP 过程中求出 设 match[j][k] = 1 代表 T 匹配到 j 时,主串字符为 k 时,新增答案
nxt2[j][k] 代表 T 匹配到 j 时,主串字符为 k 时,下一个失配位置
suf[i][j] = match[j][S[i]] + suf[i+1][nxt[j][S[i]]]
所以 suf可以从后往前 DP
而 match[j][k] 和 nxt2[j][k] 可以 O(m*26) 的时间内暴力求
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 50005;
const int M = 105;
char y[N], x[M];
int nxt[N];
void GetNxt(char x[], int m)
{
int i = 0, j = -1;
nxt[0] = -1;
while (i < m)
{
while (j != -1 && x[i] != x[j]) j = nxt[j];
nxt[++i] = ++j;
}
}
int t, n, m, q;
int pre[N];
int num[N][M];
int suf[N][M];
int nxt2[M][256];
bool match[M][256];
void init()
{
memset(pre, 0, sizeof(pre));
memset(num, 0, sizeof(num));
memset(match, 0, sizeof(match));
memset(suf, 0, sizeof(suf));
int j = 0;
for (int i = 0; i < n; i++)
{
while (j != -1 && y[i] != x[j]) j = nxt[j];
j++;
if (j == m) pre[i]++, j = nxt[j];
num[i][j]++;
pre[i] += pre[i-1];
}
for (int i = 1; i < n; i++)
{
pre[i] += pre[i-1];
for (int j = 0; j < m; j++)
num[i][j] += num[i-1][j];
}
for (int i = 0; i < m; i++)
for (int j = 'a'; j <= 'z'; j++)
{
int k = i;
while (k != -1 && x[k] != j) k = nxt[k];
k++;
if (k == m) match[i][j] = 1, k = nxt[k];
nxt2[i][j] = k;
}
for (int i = n-1; i >= 0; i--)
for (int j = 0; j < m; j++)
suf[i][j] = match[j][y[i]] + suf[i+1][nxt2[j][y[i]]];
for (int i = n-1; i >= 0; i--)
for (int j = 0; j < m; j++)
suf[i][j] += suf[i+1][j];
}
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d%d", &n, &m, &q);
scanf("%s%s", y, x);
GetNxt(x, m);
init();
while (q--)
{
int l, r; scanf("%d%d", &l, &r);
l--, r--;
long long ans = 1LL * (n-r)*pre[l];
for (int i = 0; i < m; i++)
ans += 1LL * num[l][i] * suf[r][i];
printf("%lld\n", ans);
}
}
}

  

HDU 6068 - Classic Quotation | 2017 Multi-University Training Contest 4的更多相关文章

  1. hdu 6068 Classic Quotation

    题 QAQ http://acm.hdu.edu.cn/showproblem.php?pid=6068 2017 Multi-University Training Contest - Team 4 ...

  2. HDU 6068 Classic Quotation KMP+DP

    Classic Quotation Problem Description When online chatting, we can save what somebody said to form h ...

  3. HDU 6170 - Two strings | 2017 ZJUT Multi-University Training 9

    /* HDU 6170 - Two strings [ DP ] | 2017 ZJUT Multi-University Training 9 题意: 定义*可以匹配任意长度,.可以匹配任意字符,问 ...

  4. hdu 6301 Distinct Values (2018 Multi-University Training Contest 1 1004)

    Distinct Values Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  5. hdu 5288 OO’s Sequence(2015 Multi-University Training Contest 1)

    OO's Sequence                                                          Time Limit: 4000/2000 MS (Jav ...

  6. hdu 5416 CRB and Tree(2015 Multi-University Training Contest 10)

    CRB and Tree                                                             Time Limit: 8000/4000 MS (J ...

  7. HDU 4944 FSF’s game(2014 Multi-University Training Contest 7)

    思路:  ans[n]=  ans[n-1] + { (n,1),(n,2).....(n,n)}  现在任务 是 计算  { (n,1),(n,2).....(n,n)}(k=n的任意因子) 很明显 ...

  8. HDU 4940 Destroy Transportation system(2014 Multi-University Training Contest 7)

    思路:无源汇有上下界可行流判定, 原来每条边转化成  下界为D  上界为 D+B   ,判断是否存在可行流即可. 为什么呢?  如果存在可行流  那么说明对于任意的 S 集合流出的肯定等于 流入的, ...

  9. HDU 4627 The Unsolvable Problem 2013 Multi-University Training Contest 3

    给你一个数 n ( 2 <= n <= 109 ),现在需要你找到一对数a, b (a + b = n),并且使得LCM(a, b)尽可能的大,然后输出最大的 LCM(a, b). (为什 ...

随机推荐

  1. js中遍历对象的属性和值的方法

    鉴于循环目标是个对象,length是为undefined,用map等对数组的循环方法不行,对象就用此下方法 for(var key in _this.lists.medicines){ medicin ...

  2. loadrunner如何监控linux,以及重点指标分析

    监控UNIX一. lr监控UNIX ,UNIX先启动一rstatd服务 以下是在IBM AIX系统中启动rstatd服务的方法: 1. 使用telnet以root用户的身份登录入AIX系统 2. 在命 ...

  3. java源码--ArrayList

    1.1.ArrayList概述 1)ArrayList是可以动态增长和缩减的索引序列,它是基于数组实现的List类. 2)该类封装了一个动态再分配的Object[]数组,每一个类对象都有一个capac ...

  4. 聊聊BIO、NIO与AIO的区别

    题目:说一下BIO/AIO/NIO 有什么区别?及异步模式的用途和意义? 1F 说一说I/O首先来说一下什么是I/O? 在计算机系统中I/O就是输入(Input)和输出(Output)的意思,针对不同 ...

  5. python-day4(正式学习)

    数据类型 不同种类的变量值用不同的数据类型来描述 数字类型 整形:int 定义方式: name(变量名)=(赋值符号)180(变量值) name=int(180) 当变量值为小数时,自动向下取整 运算 ...

  6. ASP.NET Core 2.0 中读取 Request.Body 的正确姿势

    原文:ASP.NET Core 中读取 Request.Body 的正确姿势 ASP.NET Core 中的 Request.Body 虽然是一个 Stream ,但它是一个与众不同的 Stream ...

  7. json树迭代

    getArray(data){ for (var i in data) { if(data[i].disabled){ data[i].disabled = false } if(data[i].ch ...

  8. 安卓开发之SimpleAdapter的使用

    package com.lidaochen.test; import android.support.v7.app.AppCompatActivity; import android.os.Bundl ...

  9. 如何对Linux内核参数进行优化?

    打开配置文件 vi /etc/sysctl.conf 输入配置,如下是内核优化的参数 # TCP三次握手建立阶段接收SYN请求队列的最大长度,默认为1024(将其设置得大一些可以使出现Nginx繁忙来 ...

  10. 使用postman修改SAP Marketing Cloud contact主数据

    Marketing Cloud里的contact主数据,创建成功后也不是所有字段都能够被修改.在Personal data区域的字段是可以被修改的. 比如我在"客户属性"字段里维护 ...