「Loj 2742「JOI Open 2016」销售基因链」

题目链接

题目大意

给出一些只有四种字符的字符串,每次查询有多少字符串同时包含前缀 \(P\) 和后缀 \(Q\).

方法一

分析

考虑对字符串排序放入字典树中,不难发现,对于所有经过字典树中某个节点的字符串在排完序的字符串中必定是一段区间(即包含同一前缀的字符串排完序后必定连续),那么考虑在字典树的节点上维护上第一个经过改节点的时间和最后一个经过改节点的时间,那么查询前缀的时候就可以得到一个区间.同理处理后缀,按倒过来的字符串排序后建字典树.考虑对字符串重新编号,将排序后的字符串变为 \(1\sim n\),对倒过来排序的字符串按这个编号重新标号.每次查询可以得到两个区间,答案为倒过来排序的字符串查询出的区间内的编号在排序后的字符串查询出来的区间范围内的值的个数(即交集),那么按两个序列建一个坐标系,对于一次查询的贡献为两个区间在坐标系内构成的矩形中纵坐标的编号与横坐标对应的点的个数,可以离线 \(+\) 扫描线.

时间复杂度 \(\mathcal{O}(\sum|s|+\sum|p|+\sum|q|+n\log_2n)\).

代码太丑就不放了.

方法二

分析

\(\color{grey}{\sf{Limit}}\):终于做出来了,这道题的做法好秒啊.

\(\color{black}{\sf{Hua}}\color{red}{\sf{ShanLunJian}}\):这个题怎么做呀...

我把方法一告诉了他.

\(\color{black}{\sf{H}}\color{red}{\sf{uaShanLunJian}}\):离线有啥好的?

\(\color{grey}{\sf{Limit}}\):啊这...

\(\color{black}{\sf{H}}\color{red}{\sf{uaShanLunJian}}\):扫描线有啥好的?

\(\color{grey}{\sf{Limit}}\):这...

\(\color{black}{\sf{H}}\color{red}{\sf{uaShanLunJian}}\):\(\mathcal{O}(\sum|s|+\sum|p|+\sum|q|+n\log_2n)\) 的复杂度有啥好的?

\(\color{grey}{\sf{Limit}}\):...

\(\color{black}{\sf{H}}\color{red}{\sf{uaShanLunJian}}\):这个不是 &@#^@#^&@#& 就可以做到线性复杂度在线做法而且不用扫描线了吗,还贼好理解.

于是就有了方法二

感谢 SD 神仙 DS 带师 \(\color{black}{\sf{H}}\color{red}{\sf{uaShanLunJian}}\) 想出的方法.

考虑对于排序后的字符串倒过来建可持久化字典树,对于查询出来的区间(和方法一中相同),直接在可持久化字典树上查询(类似主席树做到区间查询 Kth),然后就没了.

利用字典树对字符串排序可以做到线性复杂度(应该是字典树的经典操作吧,不讲了).

时间复杂度 \(\mathcal{O}(\sum|s|+\sum|p|+\sum|q|+n)\),因为我写得很丑,常数巨大.

代码更加丑了,就不放了.

提交记录

想要看代码的自己看提交记录吧.

方法一的提交记录

方法二的提交记录

你可能感兴趣的:(「Loj 2742「JOI Open 2016」销售基因链」)