#P3526. 「IOI2021」修改 DNA

「IOI2021」修改 DNA

题目描述

注意:在 LibreOJ 上,由于语言限制,目前只支持以下语言的提交:

  • C++(标准为 C++ 11 及以上)

请在提交源代码前添加 #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)
  • a,ba, b:长度为 nn 的字符串,表示两个待分析的 DNA 序列。
  • 恰好调用此函数一次,且发生在任何对 get_distance 的调用之前。
int get_distance(int x, int y)
  • x,yx, y:待分析的子串的开始和结束下标。
  • 此函数应返回子串 a[xy]a[x \ldots y]b[xy]b[x \ldots y] 的修改距离。
  • 恰好调用此函数 qq 次。

评测程序示例

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

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

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

  • 1+i1 + i0iq10 \le i \le q - 1)行:第 ii 次调用 get_distance 的返回值。
6 3
ATACAT
ACTATA
1 3
4 5
3 5

2
1
-1

数据范围与提示

对于所有数据:

  • 1n,q1000001 \le n, q \le 100 \, 000
  • 0xyn10 \le x \le y \le n - 1
  • aabb 的每个字符都是 ATC 之⼀
子任务 分值 特殊限制
11 2121 yx2y - x \le 2
22 2222 q500q \le 500yx1000y - x \le 1000aabb 的每个字符是 AT
33 1313 aabb 的每个字符是 AT
44 2828 q500q \le 500yx1000y - x \le 1000
55 1616 没有额外的约束条件