【HDOJ】4426 Palindromic Substring
综合性很强的一道题目,结合manacher,后缀数组,哈希,RMQ,二分可解。
基本思路是通过manacher可以找到所有可能的回文串,哈希去重,后缀数组二分找数目。最后暴力求解。
需要注意kth需要为__int64。
- /* 4426 */
- #include <iostream>
- #include <sstream>
- #include <string>
- #include <map>
- #include <queue>
- #include <set>
- #include <stack>
- #include <vector>
- #include <deque>
- #include <algorithm>
- #include <cstdio>
- #include <cmath>
- #include <ctime>
- #include <cstring>
- #include <climits>
- #include <cctype>
- #include <cassert>
- #include <functional>
- #include <iterator>
- #include <iomanip>
- using namespace std;
- //#pragma comment(linker,"/STACK:102400000,1024000")
- #define sti set<int>
- #define stpii set<pair<int, int> >
- #define mpii map<int,int>
- #define vi vector<int>
- #define pii pair<int,int>
- #define vpii vector<pair<int,int> >
- #define rep(i, a, n) for (int i=a;i<n;++i)
- #define per(i, a, n) for (int i=n-1;i>=a;--i)
- #define clr clear
- #define pb push_back
- #define mp make_pair
- #define fir first
- #define sec second
- #define all(x) (x).begin(),(x).end()
- #define SZ(x) ((int)(x).size())
- #define lson l, mid, rt<<1
- #define rson mid+1, r, rt<<1|1
- const __int64 mod = 777777777LL;
- const int seed = ;
- const int INF = 0x3f3f3f3f;
- const int maxn = 1e5+;
- // input
- char s[maxn];
- int val[];
- __int64 V[maxn];
- // manacher
- char ss[maxn*];
- int P[maxn*];
- // sa
- int a[maxn];
- int height[maxn], sa[maxn], rrank[maxn];
- int wa[maxn], wb[maxn], wc[maxn], wv[maxn];
- // RMQ
- int dp[maxn][];
- // Hash
- unsigned __int64 H[maxn];
- // init
- unsigned __int64 Base[maxn], Power[maxn];
- vpii pal;
- set<unsigned __int64> st;
- void init() {
- Base[] = Power[] = ;
- rep(i, , maxn) {
- Base[i] = 1LL * Base[i-] * % mod;
- Power[i] = 1LL * Power[i-] * seed;
- }
- }
- void init_Hash(int n) {
- H[] = s[] - 'a' + ;
- rep(i, , n)
- H[i] = H[i-] * seed + s[i]-'a'+;
- }
- unsigned __int64 getHash(int l, int r) {
- if (l == )
- return H[r];
- return H[r] - H[l-] * Power[r-l+];
- }
- bool cmp(int *r, int a, int b, int l) {
- return r[a]==r[b] && r[a+l]==r[b+l];
- }
- void da(int *r, int *sa, int n, int m) {
- int i, j, *x=wa, *y=wb, *t, p;
- for (i=; i<m; ++i) wc[i] = ;
- for (i=; i<n; ++i) wc[x[i]=r[i]]++;
- for (i=; i<m; ++i) wc[i] += wc[i-];
- for (i=n-; i>=; --i) sa[--wc[x[i]]] = i;
- for (j=,p=; p<n; j*=, m=p) {
- for (p=,i=n-j; i<n; ++i) y[p++] = i;
- for (i=; i<n; ++i) if (sa[i] >= j) y[p++] = sa[i]-j;
- for (i=; i<n; ++i) wv[i] = x[y[i]];
- for (i=; i<m; ++i) wc[i] = ;
- for (i=; i<n; ++i) wc[wv[i]]++;
- for (i=; i<m; ++i) wc[i] += wc[i-];
- for (i=n-; i>=; --i) sa[--wc[wv[i]]] = y[i];
- for (t=x,x=y,y=t,p=,x[sa[]]=, i=; i<n; ++i)
- x[sa[i]] = cmp(y, sa[i-], sa[i], j) ? p- : p++;
- }
- }
- void calheight(int *r, int *sa, int n) {
- int i, j, k = ;
- for (i=; i<=n; ++i) rrank[sa[i]] = i;
- for (i=; i<n; height[rrank[i++]]=k)
- for (k?k--:, j=sa[rrank[i]-]; r[j+k]==r[i+k]; ++k) ;
- }
- void init_RMQ(int n) {
- int i, j;
- for (i=; i<=n; ++i)
- dp[i][] = height[i];
- dp[][] = INF;
- for (j=; (<<j)<=n; ++j)
- for (i=; i+(<<j)-<=n; ++i)
- dp[i][j] = min(dp[i][j-], dp[i+(<<(j-))][j-]);
- }
- int RMQ(int l, int r) {
- if (l > r)
- swap(l, r);
- ++l;
- int k = ;
- while (<<(k+) <= r-l+)
- ++k;
- return min(dp[l][k], dp[r-(<<k)+][k]);
- }
- void Manacher(char *s, int *P, int n) {
- pal.clr();
- st.clr();
- int i, j, mx = , id = ;
- for (i=; i<n; ++i) {
- P[i] = mx>i ? min(P[*id-i], mx-i) : ;
- while (s[i+P[i]] == s[i-P[i]])
- ++P[i];
- if (i+P[i] > mx) {
- for (j=mx; j<i+P[i]; ++j) {
- int l = *i-j, r = j;
- l >>= ;
- r = (r & ) ? (r>>) : (r>>)-;
- if (l > r)
- continue;
- unsigned __int64 hval = getHash(l, r);
- if (st.find(hval) == st.end()) {
- st.insert(hval);
- pal.pb(mp(l, r));
- }
- }
- mx = i + P[i];
- id = i;
- }
- }
- }
- int getCnt(int fr, int to, int n) {
- int len = to - fr + ;
- int rankfr = rrank[fr];
- int l, r, mid, tmp;
- int L = rankfr, R = rankfr;
- // find left most
- l = , r = rankfr - ;
- while (l <= r) {
- mid = (l + r) >> ;
- tmp = RMQ(mid, rankfr);
- if (tmp >= len) {
- L = mid;
- r = mid - ;
- } else {
- l = mid + ;
- }
- }
- // find right most
- l = rankfr + , r = n;
- while (l <= r) {
- mid = (l + r) >> ;
- tmp = RMQ(rankfr, mid);
- if (tmp >= len) {
- R = mid;
- l = mid + ;
- } else {
- r = mid - ;
- }
- }
- return R - L + ;
- }
- void init_Val(int n) {
- V[] = val[s[]-'a'];
- rep(i, , n)
- V[i] = (V[i-] * + val[s[i]-'a']) % mod;
- }
- __int64 getVal(int l, int r) {
- if (l == )
- return V[r];
- return (V[r] - V[l-] * Base[r-l+]%mod + mod) % mod;
- }
- void printSa(int n) {
- for (int i=; i<=n; ++i)
- printf("%d ", sa[i]);
- putchar('\n');
- }
- void printHeight(int n) {
- for (int i=; i<=n; ++i)
- printf("%d ", height[i]);
- putchar('\n');
- }
- int main() {
- ios::sync_with_stdio(false);
- #ifndef ONLINE_JUDGE
- freopen("data.in", "r", stdin);
- freopen("data.out", "w", stdout);
- #endif
- int t;
- int n, q;
- __int64 kth;
- int ans;
- vpii vc;
- init();
- scanf("%d", &t);
- while (t--) {
- scanf("%d %d", &n, &q);
- scanf("%s", s);
- // init sa
- rep(i, , n)
- a[i] = s[i]-'a'+;
- a[n] = ;
- da(a, sa, n+, );
- calheight(a, sa, n);
- init_RMQ(n);
- // init Hash
- init_Hash(n);
- // init Manacher
- int l = ;
- ss[l++] = '@';
- // ss[l++] = '#';
- rep(i, , n) {
- ss[l++] = s[i];
- ss[l++] = '#';
- }
- ss[l] = '\0';
- Manacher(ss, P, l);
- // find count of palindromic
- int sz = SZ(pal);
- rep(i, , sz) {
- wc[i] = getCnt(pal[i].fir, pal[i].sec, n);
- pal[i].sec = (pal[i].fir + pal[i].sec) >> ;
- }
- while (q--) {
- scanf("%I64d", &kth);
- rep(i, , )
- scanf("%d", &val[i]);
- init_Val(n);
- vc.clr();
- rep(i, , sz) {
- int tmp = getVal(pal[i].fir, pal[i].sec);
- vc.pb(mp(tmp, wc[i]));
- }
- sort(all(vc));
- ans = -;
- rep(i, , sz) {
- if (kth <= vc[i].sec) {
- ans = vc[i].fir;
- break;
- } else {
- kth -= vc[i].sec;
- }
- }
- printf("%d\n", ans);
- }
- putchar('\n');
- }
- #ifndef ONLINE_JUDGE
- printf("time = %d.\n", (int)clock());
- #endif
- return ;
- }
数据发生器。
- from random import randint, shuffle
- import shutil
- import string
- def GenDataIn():
- with open("data.in", "w") as fout:
- t = 20
- bound = 10**3
- lc = list(string.lowercase)
- uc = list(string.uppercase)
- fout.write("%d\n" % (t))
- for tt in xrange(t):
- n = randint(10**4, 10**5)
- q = randint(30, 40)
- fout.write("%d %d\n" % (n, q))
- line = ""
- for j in xrange(n):
- idx = randint(0, 25)
- line += lc[idx]
- fout.write("%s\n" % (line))
- for i in xrange(q):
- kth = randint(1, 1005)
- dataList = [kth]
- for j in xrange(26):
- val = randint(0, 25)
- dataList.append(val)
- fout.write(" ".join(map(str, dataList)) + "\n")
- def MovDataIn():
- desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
- shutil.copyfile("data.in", desFileName)
- if __name__ == "__main__":
- GenDataIn()
- MovDataIn()
【HDOJ】4426 Palindromic Substring的更多相关文章
- 【LeetCode】Longest Palindromic Substring 解题报告
DP.KMP什么的都太高大上了.自己想了个朴素的遍历方法. [题目] Given a string S, find the longest palindromic substring in S. Yo ...
- 【leedcode】 Longest Palindromic Substring
Given a , and there exists one unique longest palindromic substring. https://leetcode.com/problems/l ...
- 【leetcode】Longest Palindromic Substring (middle) 经典
Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...
- 【翻译】Longest Palindromic Substring 最长回文子串
原文地址: http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-i.html 转载请注明出处:http:// ...
- Leetcode:【DP】Longest Palindromic Substring 解题报告
Longest Palindromic Substring -- HARD 级别 Question SolutionGiven a string S, find the longest palindr ...
- 【LeetCode5】Longest Palindromic Substring★★
1.题目描述: 2.解题思路: 题意:求一个字符串的最长回文子串. 方法一:中心扩展法.遍历字符串的每一个字符,如果存在回文子串,那么中心是某一个字符(奇数)或两个字符的空隙(偶数),然后分两种情况( ...
- 【Leetcode】Longest Palindromic Substring
问题:https://leetcode.com/problems/longest-palindromic-substring/ 给定一个字符串 S,求出 S 的最长回文子串 思路: 1. 回文:一个字 ...
- 【LeetCode】647. Palindromic Substrings 解题报告(Python)
[LeetCode]647. Palindromic Substrings 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/p ...
- 【SPOJ】Longest Common Substring II (后缀自动机)
[SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...
随机推荐
- 连接Oracle数据库的OracleHelper.cs
using System; using System.Configuration; using System.Data; using System.Data.OracleClient; using S ...
- htmlcleaner
String xpath = "//div"; Object[] myNodes = node.evaluateXPath(xpath); for (Object obj : my ...
- wampsever在win10中安装扩展掉坑
1.必须要退出wampserver 2.php pecl + 3.wampserver 64 3.0.6
- hosts文件的作用 whois查询域名信息
Whois查询域名信息 在操作系统中的路径:Window98—在Windows目录下Windows 2000/XP—在C:\WINDOWS\system32\drivers\etc目录下 内容:包 ...
- N皇后问题2
Description Examine the checkerboard below and note that the six checkers are arranged on the board ...
- N皇后摆放问题
Description 在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上. 你的任务是,对于给定的N,求出有多少种 ...
- java开发命名规范总结
一 包名的书写规范 (Package)推荐使用公司或机构的顶级域名为包名的前缀,目的是保证各公司/机构内所使用的包名的唯一性.包名全部为小写字母,且具有实际的区分意义. 1.1 一般要求1.选择有意义 ...
- 进程(Process)和线程(Thread)的关系和区别
Definition定义-------------Process进程是应用程序的一次运行活动:从操作系统核 心角度来说,进程是操作系统分配和调度系统内存资源.cpu时间片等资源的基本单位,为正在运行的 ...
- random note
今天才慢慢意识到,什么才是学习,(以思考解决问题为驱动),埋头刷分只是方法,不是目的和原动力. 既然准备读研,就要慢慢去了解研究生的生活学习方式是什么样的,涉及到哪些方面. 读研之前要选好方向,但是现 ...
- spring的三种注解管理器
1.依赖注入的注解解析器 在配置文件中; * xsd xmlns:context="http://www.springframework.org/schema/context" h ...