Codeforces Round #120 (Div. 2) D : Non-Secret Cypher
acceptされたコード
長さN(<4*10^5)の数列がある。連続する部分列で、K回以上重複する要素があるものをすべて求める問題。
acceptされたコード
#include <cstdio> #include <vector> #include <iostream> #include <algorithm> using namespace std; typedef long long int64; const int MAX_N = (int)(4e5); int N, K; int as[MAX_N]; vector<int> xs[MAX_N]; void init(){ scanf("%d%d", &N, &K); for(int i=0; i<N; ++i){ scanf("%d", as+i); } } void compress(){ vector<int> nums(as, as+N); sort(nums.begin(), nums.end()); nums.erase(unique(nums.begin(), nums.end()), nums.end()); for(int i=0; i<N; ++i){ as[i] = distance(nums.begin(), lower_bound(nums.begin(), nums.end(), as[i])); } } struct range{ int from, to; range(){} range(int from, int to):from(from), to(to){} }; bool operator< (const range& lhs, const range& rhs){ return lhs.to < rhs.to; } int64 solve(){ int64 ans = 0; compress(); for(int i=0; i<N; ++i){ xs[as[i]].push_back(i); } vector<range> rs; for(int i=0; i<MAX_N; ++i){ for(int j=0; j + K <= (int)xs[i].size(); ++j){ rs.push_back( range(xs[i][j], xs[i][j+K-1]+1) ); } } sort(rs.begin(), rs.end()); int prev = -1; for(int i=0; i<(int)rs.size(); ++i){ if(prev < rs[i].from){ ans += (int64)(N - rs[i].to + 1) * (rs[i].from - prev); } prev = max(prev, rs[i].from); } return ans; } int main(){ init(); cout << solve() << endl; return 0; }