典型90問 - 034 There are few types of elements(★4)
https://atcoder.jp/contests/typical90/tasks/typical90_ah
ベーシックなしゃくとり法
【問題】
数列の区間のうち、含まれる値の種類がK種類以下である最長の連続部分列を求めよ。
【典型ポイント】
しゃくとり法
【方針】
見たまんま、しゃくとり法の典型問題
種類の数え方には連想配列を用いる。集合だと削除処理ができないため。
#include <bits/stdc++.h> using namespace std; using ll = long long; using pll = pair<long long, long long>; constexpr char ln = '\n'; constexpr long long MOD = 1000000007; constexpr long long INF = 1000000000 + 100; constexpr long long LINF = 1000000000000000000 + 100; #define all(v) v.begin(), v.end() #define rep(i, n) for(int i=0;i<(n);i++) #define rept(i, j, n) for(int i=(j); i<(n); i++) #define rrep(i, n) for(int i=(n); i>=0; i--) template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } int main(){ int N, K; cin >> N >> K; vector<ll> A(N); rep(i, N){ cin >> A[i]; } int right = 0, res = -1; map<int, int> mp; int cnt = 0; for(int left=0; left<N; left++){//[left, right) while(right<N){ if(mp[A[right]]==0 and cnt == K)break; if(mp[A[right]] == 0)cnt++; mp[A[right]]++; right++; } chmax(res, right - left); if (left == right) right++; mp[A[left]]--; if(mp[A[left]] == 0)cnt--; } cout << res << ln; }