HDU 5371 Hotaru's problem(Manacher算法+贪心)
2015-08-11 23:50
393 查看
manacher算法详见
/article/2386531.html
题意:给一个序列,让求其最大子序列,这个子序列由三段组成,第一段和第二段对称,第一段和第三段一样。
思路:首先利用Manacher算法求出以任意两个相邻元素为中心的回文串长度,用a[i]表示i-1,i为中心的回文串长度的一半,
那么问题就转化成了求最大的x,使得a[i]>=x,a[i+x]>=x,这一步可以贪心来做。
将a[i]从大到小排序(间接排序保留下标),设a[i]在原序列的下标为j,
每次将j放入set中,然后二分找到下标大于等于j-a[i]的最小值和下标小于等于j+a[i]的最大值,
这样可以就求出ans
/article/2386531.html
题意:给一个序列,让求其最大子序列,这个子序列由三段组成,第一段和第二段对称,第一段和第三段一样。
思路:首先利用Manacher算法求出以任意两个相邻元素为中心的回文串长度,用a[i]表示i-1,i为中心的回文串长度的一半,
那么问题就转化成了求最大的x,使得a[i]>=x,a[i+x]>=x,这一步可以贪心来做。
将a[i]从大到小排序(间接排序保留下标),设a[i]在原序列的下标为j,
每次将j放入set中,然后二分找到下标大于等于j-a[i]的最小值和下标小于等于j+a[i]的最大值,
这样可以就求出ans
</pre><pre class="cpp" name="code">#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #define eps 1e-6 #define LL long long #define pii (pair<int, int>) //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int maxn = 2*100000+1000; const int INF = 0x3f3f3f3f; int s[maxn]; int p[maxn], n, a[maxn], r[maxn]; bool cmp(int t1, int t2) { return a[t1] > a[t2]; } set<int> Set; struct Manacher { void solve() { int len=n,id=0,maxlen=0; for(int i=len;i>=0;--i){//插入'#' s[i+i+2]=s[i]; s[i+i+1]=-1; } s[0]=-2; for(int i=2;i<2*len+1;++i){ if(p[id]+id>i)p[i]=min(p[2*id-i],p[id]+id-i); else p[i]=1; while(s[i-p[i]] == s[i+p[i]])++p[i]; if(id+p[id]<i+p[i])id=i; if(maxlen<p[i])maxlen=p[i]; } } } manacher; int main() { //freopen("input.txt", "r", stdin); int T; cin >> T; int kase = 0; while(T--) { scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &s[i]); s = -3; manacher.solve(); int cnt = 0; for(int i = 3; i <= 2*n; i += 2) { a[++cnt] = (p[i]-1)/2; r[cnt] = cnt; } //for(int i = 1; i <= cnt; i++) cout << a[i] << endl; sort(r+1, r+cnt+1, cmp); Set.clear(); int ans = 0; for(int i = 1; i <= cnt; i++) { Set.insert(r[i]); set<int>::iterator t1 = Set.lower_bound(r[i]-a[r[i]]); set<int>::iterator t2 = --Set.upper_bound(r[i]+a[r[i]]); ans = max(ans, max(r[i]-*t1, *t2-r[i])); } ans *= 3; printf("Case #%d: %d\n", ++kase, ans); } return 0; }
相关文章推荐
- 中文乱码问题及其解决办法
- ACL
- 黑马程序员
- HDU 1233 还是畅通工程 (克鲁斯卡尔_最小生成树+贪心)
- Java并发教程
- 实现单击EditText弹出日期选择框
- POJ 2991 Crane
- 【C语言经典实例】-寻找数组的最值
- 栈的应用实例
- 毕业两年
- 引导加载程序之争:了解 LILO 和 GRUB
- Codeforces Round #315 (Div. 2)——C. Primes or Palindromes?
- poj 1873 The Fortified Forest(凸包)
- android studio 新建module
- 2015-08-11 [豌豆荚]--研发--1面
- java基础--多线程
- hdu 3309 Roll The Cube(bfs)
- 如果牛顿是程序员,那么?
- AC自动机模板
- 在活动中使用menu