manacher算法
https://blog.csdn.net/qq_16554583/article/details/79763296
https://blog.csdn.net/qq_41923622/article/details/80109897
https://blog.csdn.net/pk__pk/article/details/79566540 这个好懂
最长回文
//马拉车算法基础模板,求最长的回文半径。 //其中init函数是把原来的字符串每个字母中间插入一个串里没有出现过的字符,其中这个字符从1开始,0的位置也用一个没出现过的字符代替。 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxm = 3e5; char s[maxm], str[maxm]; int len1, len2, p[maxm], ans; void init() { str[0] = '*'; str[1] = '#'; for(int i = 0; i < len1; i++) { str[2 * i + 2] = s[i]; str[2 * i + 3] = '#'; } len2 = len1 * 2 + 2; str[len2] = '&'; } void manacher() { int id = 0, mx = 0; for(int i = 1; i < len2; i++) { if(mx > i) p[i] = min(p[2 * id - i], mx - i); else p[i] = 1; for(; str[i + p[i] ] == str[i - p[i] ]; p[i]++); if(p[i] + i > mx) { mx = p[i] + i; id = i; } } } int main() { while(~scanf("%s", s)) { len1 = strlen(s); init(); manacher(); ans = 0; for(int i = 0; i < len2; i++) { ans = max(ans, p[i]); } printf("%d\n", ans - 1); } return 0; }
C - Best Reward
https://blog.csdn.net/deerly_/article/details/79976504
https://blog.csdn.net/ummmmm/article/details/82462464
https://vjudge.net/contest/300092#problem/G
马拉车升级
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cstdlib> #include<map> using namespace std; typedef long long LL; typedef pair<int, int> pii; const int MAXN = 250; char mmp[MAXN + 5][MAXN + 5]; int a[MAXN<<1 + 5][26], tot[MAXN<<1 + 5]; int n,m; LL ans; bool cmp(int x, int y) { if( tot[x] > 1 || tot[y] > 1 ) return false; for(int i=0;i<26;i++) { if( a[x][i]!= a[y][i] ) { return false; } } return true; } LL p[MAXN*2+5]; int manacher() { int i; int len=n; len++;len<<=1; LL ret=0,mx=0,id=0; for(i=1;i<len;i++) { if(mx>i)p[i]=min(p[id*2-i],mx-i); else p[i]=1; int o=i; while(i-p[i]>0&&i+p[i]<len&&cmp(i-p[i],i+p[i])) { p[i]++;o++; } if(tot[i]>1)p[i]=1; if(mx<p[i]+i) mx=p[i]+i,id=i; ret=max(ret,p[i]); ans+=(p[i])/2; } return ret-1; } int main() { scanf("%d%d", &n, &m); for(int i=0;i<n;i++) scanf("%s", mmp[i]); for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { for(int k=0;k<26;k++) { a[(j+1)<<1][k]=tot[(j+1)<<1]=0; } } for(int j=i;j<m;j++) { for(int k=0;k<n;k++) { if(a[(k+1)<<1][mmp[k][j]-'a']&1) tot[(k+1)<<1]--; else tot[(k+1)<<1]++; a[(k+1)<<1][mmp[k][j]-'a']++; } manacher(); } } printf("%lld\n", ans); }