综合性很强的一道题目,结合manacher,后缀数组,哈希,RMQ,二分可解。
基本思路是通过manacher可以找到所有可能的回文串,哈希去重,后缀数组二分找数目。最后暴力求解。
需要注意kth需要为__int64。

  1. /* 4426 */
  2. #include <iostream>
  3. #include <sstream>
  4. #include <string>
  5. #include <map>
  6. #include <queue>
  7. #include <set>
  8. #include <stack>
  9. #include <vector>
  10. #include <deque>
  11. #include <algorithm>
  12. #include <cstdio>
  13. #include <cmath>
  14. #include <ctime>
  15. #include <cstring>
  16. #include <climits>
  17. #include <cctype>
  18. #include <cassert>
  19. #include <functional>
  20. #include <iterator>
  21. #include <iomanip>
  22. using namespace std;
  23. //#pragma comment(linker,"/STACK:102400000,1024000")
  24.  
  25. #define sti set<int>
  26. #define stpii set<pair<int, int> >
  27. #define mpii map<int,int>
  28. #define vi vector<int>
  29. #define pii pair<int,int>
  30. #define vpii vector<pair<int,int> >
  31. #define rep(i, a, n) for (int i=a;i<n;++i)
  32. #define per(i, a, n) for (int i=n-1;i>=a;--i)
  33. #define clr clear
  34. #define pb push_back
  35. #define mp make_pair
  36. #define fir first
  37. #define sec second
  38. #define all(x) (x).begin(),(x).end()
  39. #define SZ(x) ((int)(x).size())
  40. #define lson l, mid, rt<<1
  41. #define rson mid+1, r, rt<<1|1
  42.  
  43. const __int64 mod = 777777777LL;
  44. const int seed = ;
  45. const int INF = 0x3f3f3f3f;
  46. const int maxn = 1e5+;
  47. // input
  48. char s[maxn];
  49. int val[];
  50. __int64 V[maxn];
  51. // manacher
  52. char ss[maxn*];
  53. int P[maxn*];
  54. // sa
  55. int a[maxn];
  56. int height[maxn], sa[maxn], rrank[maxn];
  57. int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
  58. // RMQ
  59. int dp[maxn][];
  60. // Hash
  61. unsigned __int64 H[maxn];
  62. // init
  63. unsigned __int64 Base[maxn], Power[maxn];
  64. vpii pal;
  65. set<unsigned __int64> st;
  66.  
  67. void init() {
  68. Base[] = Power[] = ;
  69. rep(i, , maxn) {
  70. Base[i] = 1LL * Base[i-] * % mod;
  71. Power[i] = 1LL * Power[i-] * seed;
  72. }
  73. }
  74.  
  75. void init_Hash(int n) {
  76. H[] = s[] - 'a' + ;
  77. rep(i, , n)
  78. H[i] = H[i-] * seed + s[i]-'a'+;
  79. }
  80.  
  81. unsigned __int64 getHash(int l, int r) {
  82. if (l == )
  83. return H[r];
  84. return H[r] - H[l-] * Power[r-l+];
  85. }
  86.  
  87. bool cmp(int *r, int a, int b, int l) {
  88. return r[a]==r[b] && r[a+l]==r[b+l];
  89. }
  90.  
  91. void da(int *r, int *sa, int n, int m) {
  92. int i, j, *x=wa, *y=wb, *t, p;
  93.  
  94. for (i=; i<m; ++i) wc[i] = ;
  95. for (i=; i<n; ++i) wc[x[i]=r[i]]++;
  96. for (i=; i<m; ++i) wc[i] += wc[i-];
  97. for (i=n-; i>=; --i) sa[--wc[x[i]]] = i;
  98. for (j=,p=; p<n; j*=, m=p) {
  99. for (p=,i=n-j; i<n; ++i) y[p++] = i;
  100. for (i=; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i]-j;
  101. for (i=; i<n; ++i) wv[i] = x[y[i]];
  102. for (i=; i<m; ++i) wc[i] = ;
  103. for (i=; i<n; ++i) wc[wv[i]]++;
  104. for (i=; i<m; ++i) wc[i] += wc[i-];
  105. for (i=n-; i>=; --i) sa[--wc[wv[i]]] = y[i];
  106. for (t=x,x=y,y=t,p=,x[sa[]]=, i=; i<n; ++i)
  107. x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p- : p++;
  108. }
  109. }
  110.  
  111. void calheight(int *r, int *sa, int n) {
  112. int i, j, k = ;
  113.  
  114. for (i=; i<=n; ++i) rrank[sa[i]] = i;
  115. for (i=; i<n; height[rrank[i++]]=k)
  116. for (k?k--:, j=sa[rrank[i]-]; r[j+k]==r[i+k]; ++k) ;
  117. }
  118.  
  119. void init_RMQ(int n) {
  120. int i, j;
  121.  
  122. for (i=; i<=n; ++i)
  123. dp[i][] = height[i];
  124. dp[][] = INF;
  125. for (j=; (<<j)<=n; ++j)
  126. for (i=; i+(<<j)-<=n; ++i)
  127. dp[i][j] = min(dp[i][j-], dp[i+(<<(j-))][j-]);
  128. }
  129.  
  130. int RMQ(int l, int r) {
  131. if (l > r)
  132. swap(l, r);
  133.  
  134. ++l;
  135. int k = ;
  136.  
  137. while (<<(k+) <= r-l+)
  138. ++k;
  139.  
  140. return min(dp[l][k], dp[r-(<<k)+][k]);
  141. }
  142.  
  143. void Manacher(char *s, int *P, int n) {
  144. pal.clr();
  145. st.clr();
  146.  
  147. int i, j, mx = , id = ;
  148.  
  149. for (i=; i<n; ++i) {
  150. P[i] = mx>i ? min(P[*id-i], mx-i) : ;
  151. while (s[i+P[i]] == s[i-P[i]])
  152. ++P[i];
  153. if (i+P[i] > mx) {
  154. for (j=mx; j<i+P[i]; ++j) {
  155. int l = *i-j, r = j;
  156. l >>= ;
  157. r = (r & ) ? (r>>) : (r>>)-;
  158. if (l > r)
  159. continue;
  160.  
  161. unsigned __int64 hval = getHash(l, r);
  162. if (st.find(hval) == st.end()) {
  163. st.insert(hval);
  164. pal.pb(mp(l, r));
  165. }
  166. }
  167. mx = i + P[i];
  168. id = i;
  169. }
  170. }
  171. }
  172.  
  173. int getCnt(int fr, int to, int n) {
  174. int len = to - fr + ;
  175. int rankfr = rrank[fr];
  176. int l, r, mid, tmp;
  177. int L = rankfr, R = rankfr;
  178.  
  179. // find left most
  180. l = , r = rankfr - ;
  181. while (l <= r) {
  182. mid = (l + r) >> ;
  183. tmp = RMQ(mid, rankfr);
  184. if (tmp >= len) {
  185. L = mid;
  186. r = mid - ;
  187. } else {
  188. l = mid + ;
  189. }
  190. }
  191.  
  192. // find right most
  193. l = rankfr + , r = n;
  194. while (l <= r) {
  195. mid = (l + r) >> ;
  196. tmp = RMQ(rankfr, mid);
  197. if (tmp >= len) {
  198. R = mid;
  199. l = mid + ;
  200. } else {
  201. r = mid - ;
  202. }
  203. }
  204.  
  205. return R - L + ;
  206. }
  207.  
  208. void init_Val(int n) {
  209. V[] = val[s[]-'a'];
  210. rep(i, , n)
  211. V[i] = (V[i-] * + val[s[i]-'a']) % mod;
  212. }
  213.  
  214. __int64 getVal(int l, int r) {
  215. if (l == )
  216. return V[r];
  217. return (V[r] - V[l-] * Base[r-l+]%mod + mod) % mod;
  218. }
  219.  
  220. void printSa(int n) {
  221. for (int i=; i<=n; ++i)
  222. printf("%d ", sa[i]);
  223. putchar('\n');
  224. }
  225.  
  226. void printHeight(int n) {
  227. for (int i=; i<=n; ++i)
  228. printf("%d ", height[i]);
  229. putchar('\n');
  230. }
  231.  
  232. int main() {
  233. ios::sync_with_stdio(false);
  234. #ifndef ONLINE_JUDGE
  235. freopen("data.in", "r", stdin);
  236. freopen("data.out", "w", stdout);
  237. #endif
  238.  
  239. int t;
  240. int n, q;
  241. __int64 kth;
  242. int ans;
  243. vpii vc;
  244.  
  245. init();
  246. scanf("%d", &t);
  247. while (t--) {
  248. scanf("%d %d", &n, &q);
  249. scanf("%s", s);
  250.  
  251. // init sa
  252. rep(i, , n)
  253. a[i] = s[i]-'a'+;
  254. a[n] = ;
  255. da(a, sa, n+, );
  256. calheight(a, sa, n);
  257. init_RMQ(n);
  258.  
  259. // init Hash
  260. init_Hash(n);
  261.  
  262. // init Manacher
  263. int l = ;
  264. ss[l++] = '@';
  265. // ss[l++] = '#';
  266. rep(i, , n) {
  267. ss[l++] = s[i];
  268. ss[l++] = '#';
  269. }
  270. ss[l] = '\0';
  271. Manacher(ss, P, l);
  272.  
  273. // find count of palindromic
  274. int sz = SZ(pal);
  275. rep(i, , sz) {
  276. wc[i] = getCnt(pal[i].fir, pal[i].sec, n);
  277. pal[i].sec = (pal[i].fir + pal[i].sec) >> ;
  278. }
  279.  
  280. while (q--) {
  281. scanf("%I64d", &kth);
  282. rep(i, , )
  283. scanf("%d", &val[i]);
  284. init_Val(n);
  285. vc.clr();
  286. rep(i, , sz) {
  287. int tmp = getVal(pal[i].fir, pal[i].sec);
  288. vc.pb(mp(tmp, wc[i]));
  289. }
  290. sort(all(vc));
  291. ans = -;
  292. rep(i, , sz) {
  293. if (kth <= vc[i].sec) {
  294. ans = vc[i].fir;
  295. break;
  296. } else {
  297. kth -= vc[i].sec;
  298. }
  299. }
  300. printf("%d\n", ans);
  301. }
  302. putchar('\n');
  303. }
  304.  
  305. #ifndef ONLINE_JUDGE
  306. printf("time = %d.\n", (int)clock());
  307. #endif
  308.  
  309. return ;
  310. }

数据发生器。

  1. from random import randint, shuffle
  2. import shutil
  3. import string
  4.  
  5. def GenDataIn():
  6. with open("data.in", "w") as fout:
  7. t = 20
  8. bound = 10**3
  9. lc = list(string.lowercase)
  10. uc = list(string.uppercase)
  11. fout.write("%d\n" % (t))
  12. for tt in xrange(t):
  13. n = randint(10**4, 10**5)
  14. q = randint(30, 40)
  15. fout.write("%d %d\n" % (n, q))
  16. line = ""
  17. for j in xrange(n):
  18. idx = randint(0, 25)
  19. line += lc[idx]
  20. fout.write("%s\n" % (line))
  21. for i in xrange(q):
  22. kth = randint(1, 1005)
  23. dataList = [kth]
  24. for j in xrange(26):
  25. val = randint(0, 25)
  26. dataList.append(val)
  27. fout.write(" ".join(map(str, dataList)) + "\n")
  28.  
  29. def MovDataIn():
  30. desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
  31. shutil.copyfile("data.in", desFileName)
  32.  
  33. if __name__ == "__main__":
  34. GenDataIn()
  35. MovDataIn()

【HDOJ】4426 Palindromic Substring的更多相关文章

  1. 【LeetCode】Longest Palindromic Substring 解题报告

    DP.KMP什么的都太高大上了.自己想了个朴素的遍历方法. [题目] Given a string S, find the longest palindromic substring in S. Yo ...

  2. 【leedcode】 Longest Palindromic Substring

    Given a , and there exists one unique longest palindromic substring. https://leetcode.com/problems/l ...

  3. 【leetcode】Longest Palindromic Substring (middle) 经典

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  4. 【翻译】Longest Palindromic Substring 最长回文子串

    原文地址: http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-i.html 转载请注明出处:http:// ...

  5. Leetcode:【DP】Longest Palindromic Substring 解题报告

    Longest Palindromic Substring -- HARD 级别 Question SolutionGiven a string S, find the longest palindr ...

  6. 【LeetCode5】Longest Palindromic Substring★★

    1.题目描述: 2.解题思路: 题意:求一个字符串的最长回文子串. 方法一:中心扩展法.遍历字符串的每一个字符,如果存在回文子串,那么中心是某一个字符(奇数)或两个字符的空隙(偶数),然后分两种情况( ...

  7. 【Leetcode】Longest Palindromic Substring

    问题:https://leetcode.com/problems/longest-palindromic-substring/ 给定一个字符串 S,求出 S 的最长回文子串 思路: 1. 回文:一个字 ...

  8. 【LeetCode】647. Palindromic Substrings 解题报告(Python)

    [LeetCode]647. Palindromic Substrings 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/p ...

  9. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

随机推荐

  1. 连接Oracle数据库的OracleHelper.cs

    using System; using System.Configuration; using System.Data; using System.Data.OracleClient; using S ...

  2. htmlcleaner

    String xpath = "//div"; Object[] myNodes = node.evaluateXPath(xpath); for (Object obj : my ...

  3. wampsever在win10中安装扩展掉坑

    1.必须要退出wampserver 2.php pecl + 3.wampserver 64 3.0.6

  4. hosts文件的作用 whois查询域名信息

      Whois查询域名信息 在操作系统中的路径:Window98—在Windows目录下Windows 2000/XP—在C:\WINDOWS\system32\drivers\etc目录下 内容:包 ...

  5. N皇后问题2

    Description Examine the  checkerboard below and note that the six checkers are arranged on the board ...

  6. N皇后摆放问题

    Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上.  你的任务是,对于给定的N,求出有多少种 ...

  7. java开发命名规范总结

    一 包名的书写规范 (Package)推荐使用公司或机构的顶级域名为包名的前缀,目的是保证各公司/机构内所使用的包名的唯一性.包名全部为小写字母,且具有实际的区分意义. 1.1 一般要求1.选择有意义 ...

  8. 进程(Process)和线程(Thread)的关系和区别

    Definition定义-------------Process进程是应用程序的一次运行活动:从操作系统核 心角度来说,进程是操作系统分配和调度系统内存资源.cpu时间片等资源的基本单位,为正在运行的 ...

  9. random note

    今天才慢慢意识到,什么才是学习,(以思考解决问题为驱动),埋头刷分只是方法,不是目的和原动力. 既然准备读研,就要慢慢去了解研究生的生活学习方式是什么样的,涉及到哪些方面. 读研之前要选好方向,但是现 ...

  10. spring的三种注解管理器

    1.依赖注入的注解解析器 在配置文件中; * xsd xmlns:context="http://www.springframework.org/schema/context" h ...