hdu 3613 (manacher + 判斷枚舉的子串是不是迴文串)

題意:
先給你每個字母的價值和一個字符串,讓你切一刀,這個字符串的總價值爲左子串的價值+右子串的價值,如果子串是迴文串,價值就是所有字符的價值之和,否則就是0。

思路:
先馬拉車預處理一下,然後從0到len-2遍歷,枚舉左邊和右邊的子串,要判斷左邊或者右邊是不是迴文串可以寫個函數,要知道在manacher如果迴文串中心在pos位置,左端點和右端點在原串的位置那個式子就行了,然後用個前綴和算出串的價值。

#include <bits/stdc++.h>

#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define ford(i, a, b) for (int i = (int)(a); i >= (int)b; --i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
#define rep(i, l, r) for (int i = (l); i <= (r); i++)
#define per(i, r, l) for (int i = (r); i >= (l); i--)
#define ms(x, y) memset(x, y, sizeof(x))
 
using namespace std;
 
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;
 
template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn = 500001+100;
int tc, val[30], pref[maxn];
char ma[maxn << 1], s[maxn];
int mp[maxn << 1];

int manacher(char s[], int len) {
	int l = 0, ans = 1;
	ma[l++] = '$';
	ma[l++] = '#';
	for (int i = 0; i < len; ++i) {
		ma[l++] = s[i];
		ma[l++] = '#';
	}
	ma[l] = 0;
	int mx = 0, id = 0;
	for (int i = 0; i < l; ++i) {
		mp[i] = mx > i ? min(mp[2 * id - i], mx - i) : 1;
		while (ma[i - mp[i]] == ma[i + mp[i]]) ++mp[i];
		if (i + mp[i] > mx) {
			mx = i + mp[i];
			id = i;
		}
		if (mp[i] - 1 > ans) ans = mp[i] - 1;
	}
	return ans;
}
int getL(int pos) {
    return ((pos -(mp[pos] - 1) + 1) / 2 - 1);
}
int getR(int pos) {
    return ((pos + (mp[pos] - 1) - 1) / 2 - 1);
}
int solve(int l, int r) {
	int ml = (l+1)<<1, mr = (r+1)<<1;
    int mid = (ml+mr)>>1;
    if (getL(mid) == l && getR(mid) == r) return (pref[r+1]-pref[l]);
    else return 0;
}
 
int main() {
	ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.precision(10);
    cout << fixed;
#ifdef LOCAL_DEFINE
#endif
	
	cin >> tc;
	while (tc--) {
		forn(i, 26) cin >> val[i];
		cin >> s;
		int len = strlen(s);
        pref[0] = 0;
        forn(i, len) {
            pref[i+1] = pref[i]+val[int(s[i]-'a')];
        }
		manacher(s, len);
		int ans = 0;
		for (int i = 0; i < len-1; ++i) {
			ans = max(ans, solve(0, i)+solve(i+1, len-1));
		}
		cout << ans << '\n';
	}
		
#ifdef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章