#L3526. 「IOI2021」修改 DNA

    ID: 5971 传统题 1000ms 256MiB 尝试: 1 已通过: 1 难度: 10 上传者: 标签>字符串哈希和哈希表数据结构前缀和其他构造组合计数

「IOI2021」修改 DNA

题目描述

请在提交源代码前添加 #include "dna.h"

Grace 是一名生物学家,在新加坡的一个生物信息学公司工作。她的一部分工作是分析不同有机体的 DNA 序列。DNA 序列是包含字符 ATC 的字符串。注意在本题中,DNA 序列不包含字符 G

定义一次修改是把 DNA 序列中的两个元素交换位置的操作。例如,通过交换加粗的字符 AC,一次修改可以把 ACTA 转化为 AATC

两个序列的修改距离是把一个序列转化为另一个序列所用的最少修改次数。如果不能通过修改把一个序列转化为另一个序列,那么这两个序列的修改距离为 1-1

Grace 正在分析两个 DNA 序列 aabb,每个都由 nn 个元素组成,下标从 00n1n - 1。你的任务是帮助 Grace 回答以下形式的 qq 个问题:子串 a[xy]a[x \ldots y]b[xy]b[x \ldots y] 的修改距离是多少?这里,DNA 序列 ss 的子串 s[xy]s[x \ldots y] 定义为 ss 的下标从 xxyy(包括 xxyy)的连续字符序列。也就是说,s[xy]s[x \ldots y] 是序列 s[x]  s[x+1]    s[y]s[x] \; s[x + 1] \; \ldots \; s[y]


实现细节

你要实现以下函数:

void init(string a, string b)
  • aa, bb:长度为 nn 的字符串,表示两个待分析的 DNA 序列。
  • 恰好调用此函数一次,且发生在任何对 get_distance 的调用之前。
int get_distance(int x, int y)
  • xx, yy:待分析的子串的开始和结束下标。
  • 此函数应返回子串 a[xy]a[x \ldots y]b[xy]b[x \ldots y] 的修改距离。
  • 恰好调用此函数 qq 次。

评测程序示例

评测程序示例按以下格式读取输入:

  • 11 行:n  qn \; q
  • 22 行:aa
  • 33 行:bb
  • 4+i4 + i 行(0iq10 \le i \le q - 1):x  yx \; y,是第 ii 次调用 get_distance 的参数。

评测程序示例按以下格式打印你的答案:

  • 1+i1 + i 行(0iq10 \le i \le q - 1):第 ii 次调用 get_distance 的返回值。

样例

输入:

6 3
ATACAT
ACTATA
1 3
4 5
3 5

输出:

2
1
-1

解释
考虑以下调用:

init("ATACAT", "ACTATA")
  1. 如果评测程序调用 get_distance(1, 3),那么该调用应返回 a[13]a[1 \ldots 3]b[13]b[1 \ldots 3](也就是序列 TACCTA)之间的修改距离。通过 22 次修改可以把 TAC 转化为 CTA

    • TACCAT
    • 然后是 CATCTA
      无法通过比 22 次更少的修改完成该转化。因此,该调用应返回 22
  2. 如果评测程序调用 get_distance(4, 5),那么该调用应返回序列 ATTA 之间的修改距离。通过一次修改可以把 AT 转化为 TA,而且显然至少需要一次。因此,该调用应返回 11

  3. 如果评测程序调用 get_distance(3, 5),由于无法通过修改将序列 CAT 转化为 ATA,因此该调用应返回 1-1


数据范围与提示

对于所有数据:

  • 1n,q1000001 \le n, q \le 100 \, 000
  • 0xyn10 \le x \le y \le n - 1
  • aabb 的每个字符都是 ATC 之一

子任务

子任务 分值 特殊限制
1 2121 yx2y - x \le 2
2 2222 q500q \le 500yx1000y - x \le 1000aabb 的每个字符是 AT
3 1313 aabb 的每个字符是 AT
4 2828 q500q \le 500yx1000y - x \le 1000
5 1616 没有额外的约束条件