码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1335E2 - Three Blocks Palindrome (贪心)

时间:2020-04-29 23:57:08      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:最大   ali   codeforce   eof   lse   mem   cout   回文   mat   

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 ‘\n‘
#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 (贪心)

标签:最大   ali   codeforce   eof   lse   mem   cout   回文   mat   

原文地址:https://www.cnblogs.com/limil/p/12805548.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!