Boring Non-Palindrome
题目链接:https://codeforces.com/gym/102307/problem/B
思路
因为只能从末尾加字符串,让其变成回文串,那么就可以找到以原字符串末尾结束的最长回文子串T(马拉车做),然后把前面不属于T的部分命名成T2。然后输出原字符串,再反序输出T2。
代码
#include<bits/stdc++.h> #define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; const int maxn = 1e4+10; using namespace std; string s; int ans[maxn],str[maxn],lef[maxn]; int build(const string &s){ int n = s.length(), m = (n + 1)*2, ret = 0; str[0] = '\n'; str[m] = '\t'; str[1] = '\r'; ans[1] = 1; for (int i = 1; i <= n; i++) str[i*2] = s[i - 1], str[i*2+1] = '\r'; ans[1] = 1; for (int r = 0, p = 0, i = 2; i < m; ++i){ if (r > i) ans[i] = min(r - i, ans[p * 2 - i]); else ans[i] = 1; while(str[i - ans[i]] == str[i + ans[i]]) ++ans[i]; if (i + ans[i] > r) r = i + ans[i], p = i; ret = max(ret, ans[i] - 1); } for (int i = 2; i < m; i++) if (lef[i - ans[i] + 1] < i + 1) lef[i - ans[i] + 1] = i + 1; for (int i = 1; i <= m; i++) if (lef[i] < lef[i - 1]) lef[i] = lef[i - 1]; return ret; } int left(int x){ return lef[(x + 1) << 1] - ((x+1) << 1); } int main(){ ios; cin>>s; int len = s.length(); build(s); int lenr = 1; for(int i = 0;i<len;i++){ int ll = left(i); if(i + ll - 1 == len-1) { lenr = ll; break; } } cout<<s; for(int i = len-lenr-1;i>=0;i--) cout<<s[i]; return 0; }