AGC044D Guess the Password

题意:你需要猜一个长度未知的密码串\(S\)。你有\(Q\)次询问机会。每次你可以输出一个串\(T\),交互库会返回一个整数,表示\(S\)\(T\)的距离。定义两个串的距离为一个串通过在任意位置添加、删除或修改字符使两串相等的最小步数。

\(|S|\leq 128,Q=850\)

题解:考虑先知道这个串由哪些字符组成。设\(cnt_i\)表示第\(i\)种字符出现的次数,第\(i\)次询问得到的答案为\(w_i\),那么我们用62次机会,每次令$T=\(128个字符\)i\(,那么我们可以得到这样的关系:\)w_i=128-cnt_i+L-cnt_i$。前面的\(128-cnt_i\)是先把多余的字符\(i\)删掉,后面的\(L-cnt_i\)是补上其余的61种字符。我们将62个等式累加起来,发现等式右边的值为\(128\times 62+60\times L\)。把\(L\)算出来,就能得到所有的\(cnt_i\)

接下来考虑还原串\(S\)

发现一个关键的性质:如果\(T\)\(S\)的子序列,那么返回的答案一定是\(|S|-|T|\)。利用这个性质,我们可以使用归并排序的方法,每次将两种字符合并在一起。单次合并所需要的查询次数为两边的串长和。这样,总操作次数就是\(LlogL+62\)

posted @ 2020-07-17 18:04  Purple_wzy  阅读(277)  评论(0编辑  收藏  举报