回文(pal.c/cpp/pas)
1 题目描述
闲着无聊的YGH秒掉上面两道题之后,开始思考有趣的回文串问题了。
他面前就有一个漂浮着的字符串。显然YGH是会manacher的,于是他随手求出了这个字符串的回文子串个数。但是他不满足于这个问题,他打算搞出一个数据结构,能够快速求出这个字符串下标为[l,r]的子串的回文子串个数(相同的回文子串需重复计数)。但是这实在是太简单啦,他打算考考辣鸡YYR,可是辣鸡至极的YYR完全没有思路。
于是,YGH扬长而去,在衣袖带起的一小片尘土之中,沉思的YYR依旧在那里。
2 输入格式
第一行为一个字符串S。
第二行一个整数T,表示询问次数。
接下来T行,每行两个整数l、r,表示查询字符串S下标为[l,r]的子串的答案。
3 输出格式
输出T行,每行一个整数表示这个询问的答案。
样例输入
ababaab
2
1 3
3 7
样例输出
4
8
数据范围与约定
对于20%的数据,保证 |S| , T<=500
对于40%的数据,保证 |S| , T <=5000
对于100%的数据,保证 |S| <=5000 , T<=100000
思路:
神奇的dp,本来还以为良心的YYR释放了善意。。。
前20%的数据:大暴力
前40%的数据:每次跑一遍manacher,计算这个子串的回文子串数,复杂度O(n*T)。
前100%的数据:考虑DP,先处理出g[i][j]表示i到j这一段是否为回文串,很容易通过g[i+1][j-1]推得。再用f[i][j]表示i到j这一个子串的回文子串数,那么f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1]+g[i][j]。再处理一下边界情况就好。复杂度O(n^2+T)。
对了,这个数据结构就是二维数组。