日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU 5371 Manacher Hotaru's problem

發布時間:2023/12/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 5371 Manacher Hotaru's problem 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

求出一個連續子序列,這個子序列由三部分ABC構成,其中AB是回文串,A和C相同,也就是BC也是回文串。

求這樣一個最長的子序列。

Manacher算法是在所有兩個相鄰數字之間插入一個特殊的數字,比如-1,

Manacher算法跑完之后,就計算出每個數字為中心的回文子序列的最大長度

由題意可以知道,AB和BC必然是長度為偶數的回文串。所以我們枚舉回文串的中心就枚舉相鄰兩個數字之間的縫隙,也就是那些-1

把AB中間的間隙叫做左中心i,BC之間的間隙叫做右中心j,那么如果兩個中心的范圍能夠互相覆蓋,那么就找到一個符合條件的連續子序列。

做法就是枚舉左中心i,在左中心的范圍內枚舉右中心j,然后維護一個最大值即可。

在枚舉j的時候不要直接從[i+1, i + p[i] - 1]枚舉,會超時的。

比如說我們維護的最大值是ans,那么直接從 i + ans 開始枚舉,因為之前的區間即使找到合法子序列也并不能更新這個最大值。

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 100000 + 10; 8 9 int n, tot; 10 int a[maxn], b[maxn * 2]; 11 12 int p[maxn * 2]; 13 14 void Manacher() 15 { 16 int id, mx = 0; 17 p[0] = 0; 18 for(int i = 1; i < tot; i++) 19 { 20 if(mx > i) p[i] = min(p[id * 2 - i], mx - i); 21 else p[i] = 1; 22 while(b[i + p[i]] == b[i - p[i]]) p[i]++; 23 if(i + p[i] > mx) { mx = i + p[i]; id = i; } 24 } 25 } 26 27 int main() 28 { 29 int T; scanf("%d", &T); 30 for(int kase = 1; kase <= T; kase++) 31 { 32 scanf("%d", &n); 33 for(int i = 0; i < n; i++) scanf("%d", a + i); 34 35 b[0] = -2, b[1] = -1; 36 tot = 2; 37 for(int i = 0; i < n; i++) 38 { 39 b[tot++] = a[i]; 40 b[tot++] = -1; 41 } 42 43 Manacher(); 44 45 int ans = 1; 46 for(int i = 3; i < tot; i += 2) 47 { 48 for(int j = ans; j <= p[i]; j += 2) 49 if(p[i + j - 1] >= j) ans = j; 50 } 51 52 ans = ans / 2 * 3; 53 printf("Case #%d: %d\n", kase, ans); 54 } 55 56 return 0; 57 } 代碼君

?

轉載于:https://www.cnblogs.com/AOQNRMGYXLMV/p/4732720.html

總結

以上是生活随笔為你收集整理的HDU 5371 Manacher Hotaru's problem的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。