Codeforces 1335E2 - Three Blocks Palindrome (贪心)

Posted limil

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1335E2 - Three Blocks Palindrome (贪心)相关的知识,希望对你有一定的参考价值。

Description

思路

由于(a_i)的取值非常小,所以把每个值所在坐标从小到大存起来。然后枚举每个(a_i)为回文的左右边界可得的最大长度。
枚举过程中,求两个(a_i)形成的区间中包含的重复次数最多的数。由于区间越大,重复的个数越多,所以从(a_i)的最左右两边到中间枚举。
统计区间某个数的重复次数用前缀和。

#include <bits/stdc++.h>
 
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
#define endl ‘
‘
#define inf 0x3f3f3f3f
const int M = 998244353;
 
int arr[N];
int cnt[N][202];
vector<int> pos[202];
int num[202];
 
int work(int l, int r) {
    if(r < l) return 0;
    int res = 0;
    for(int i = 1; i <= 200; i++) {
        res = max(res, cnt[r][i] - cnt[l - 1][i]);
    }
    return res;
}
 
int main() {
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t--) {
        int n;
        cin >> n;
        
        for(int i = 1; i <= 200; i++) pos[i].clear();
        for(int i = 0; i <= n; i++) memset(cnt[i], 0, sizeof cnt[i]);
 
        for(int i = 1; i <= n; i++) {
            cin >> arr[i];
            cnt[i][arr[i]]++;
            pos[arr[i]].push_back(i);
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= 200; j++) {
                cnt[i][j] += cnt[i - 1][j];
            }
        }
        int ans = 1;
        for(int i = 1; i <= 200; i++) {
            if(pos[i].size() < 2) continue;
            int l = 0, r = pos[i].size() - 1;
            while(l <= r) {
                ans = max(ans, (l + 1) * 2 - (l == r) + work(pos[i][l] + 1, pos[i][r] - 1));
                l++, r--;
            }
        }
        cout << ans << endl;
    } 
 
}

以上是关于Codeforces 1335E2 - Three Blocks Palindrome (贪心)的主要内容,如果未能解决你的问题,请参考以下文章

codeforces-1335-E Three Blocks Palindrome

codeforces 653A A. Bear and Three Balls(水题)

Divide by Three CodeForces - 792C

题解[CodeForces1154A]Restoring Three Numbers

Codeforces Round #485 (Div. 2) C. Three displays

CodeForces - 1131D(Three Integers)