Problem:
Rope
JOI is a baby playing with a rope. The rope has length $N$, and it is placed as a straight line from left to right. The rope consists of $N$ cords. The cords are connected as a straight line. Each cord has length 1 and thickness 1. In total, $M$ colors are used for the rope. The color of the $i$-th cord from left is $C_i$ ($1 \leq C_i \leq M$).
JOI is making the rope shorter. JOI repeats the following procedure until the length of the rope becomes 2.
Let $L$ be the length of the rope. Choose an integer $j$ ($1 \leq j < L$). Shorten the rope by combining cords so that the point of length $j$ from left on the rope becomes the leftmost point. More precisely, do the following:
If $j \leq L/2$, for each $i$ ($1 \leq i \leq j$), combine the $i$-th cord from left with the ($2j - i + 1$)-th cord from left. By this procedure, the rightmost point of the rope becomes the rightmost point. The length of the rope becomes $L - j$.
If $j > L/2$, for each $i$ ($2j - L + 1 \leq i \leq j$), combine the $i$-th cord from left with the ($2j - i + 1$)-th cord from left. By this procedure, the leftmost point of the rope becomes the rightmost point. The length of the rope becomes $j$.
If a cord is combined with another cord, the colors of the two cords must be the same. We can change the color of a cord before it is combined with another cord. The cost to change the color of a cord is equal to the thickness of it. After adjusting the colors of two cords, they are combined into a single cord; its thickness is equal to the sum of thicknesses of the two cords.
JOI wants to minimize the total cost of procedures to shorten the rope until it becomes length 2. For each color, JOI wants to calculate the minimum total cost of procedures to shorten the rope so that the final rope of length 2 contains a cord with that color.
Your task is to solve this problem instead of JOI.
Task
Given the colors of the cords in the initial rope, write a program which calculates, for each color, the minimum total cost of procedures to shorten the rope so that the final rope of length 2 contains a cord with that color.
Input
Read the following data from the standard input.
The first line of input contains two space separated integers $N$, $M$. This means the rope consists of $N$ cords, and $M$ colors are used for the cords.
The second line contains $N$ space separated integers $C_1, C_2, ... ,C_N$. This means the color of the $i$-th cord from left is $C_i$ ($1 \leq C_i \leq M$).
Output
Write $M$ lines to the standard output. The $c$-th line ($1 \leq c \leq M$) contains the minimum total cost of procedures to shorten the rope so that the final rope of length 2 contains a cord with color $c$.
Constraints
All input data satisfy the following conditions.
$  2 \leq N \leq 1 000 000． $
$  1 \leq M \leq N．$
$  1 \leq C_i \leq M (1 \leq i \leq N)．$
For each $c$ with $1 \leq c \leq M$, there exists an integer $i$ with $C_i = c$.
Sample Input and Output
Sample Input 1
5 3
1 2 3 3 2
Sample Output 1
2
1
1

...(truncated)

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef unsigned long long int ull;

#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
#define NUM 1000005

int W, M;
int input[NUM];
int number[NUM];
int BIT[NUM], ans[NUM];
vector<int> V[NUM];
int N;
int table[6 * NUM];

void init(int first_N) {
    N = 1;
    while (N < first_N) N *= 2;
}

void update(int loc, int value) {
    loc += N - 1;
    table[loc] += value;

    while (loc > 0) {
        loc = (loc - 1) / 2;
        table[loc] = max(table[2 * loc + 1], table[2 * loc + 2]);
    }
}

int query(int search_left, int search_right, int node_id, int node_left, int node_right) {
    if (search_right < node_left || search_left > node_right) return -BIG_NUM;
    if (search_left <= node_left && search_right >= node_right) {
        return table[node_id];
    }
    int mid = (node_left + node_right) / 2;
    int left_max = query(search_left, search_right, 2 * node_id + 1, node_left, mid);
    int right_max = query(search_left, search_right, 2 * node_id + 2, mid + 1, node_right);
    return max(left_max, right_max);
}

int main() {
    scanf("%d %d", &W, &M);

    if (M == 1) {
        printf("0\n");
        return 0;
    }

    fill(number, number + M, 0);
    fill(ans, ans + M, BIG_NUM);

    for (int i = 0; i < W; i++) {
        scanf("%d", &input[i]);
        input[i]--;
        number[input[i]]++;
    }

    init(M);

    for (int start = 0; start <= 1; start++) {
        for (int i = start; i + 1 <= W - 1; i += 2) {
            V[input[i]].push_back(input[i + 1]);
            V[input[i + 1]].push_back(input[i]);
        }

        fill(table, table + 2 * N - 1, 0);
        for (int i = 0; i < M; i++) {
            update(i, number[i]);
        }

        for (int i = 0; i < M; i++) {
            for (int k : V[i]) {
                update(k, -1);
            }
            int tmp = max(query(0, i - 1, 0, 0, N - 1), query(i + 1, M - 1, 0, 0, N - 1));
            ans[i] = min(ans[i], W - (number[i] + tmp));
            for (int k : V[i]) {
                update(k, 1);
            }
        }

        for (int i = 0; i < M; i++) {
            V[i].clear();
        }
    }

    for (int i = 0; i < M; i++) {
        printf("%d\n", ans[i]);
    }

    return 0;
}
accuracy: 1
time_ms: 910
memory_kb: 82952
final_rank: 3

code_snippet: #include <iostream>
#include <map>
#include <queue>
#include <tuple>
#include <algorithm>
#include <functional>
using namespace std;

class RangeMax {
public:
	int size_;
	vector<int> dat;

	void init(int sz) {
		size_ = 1;
		while (size_ <= sz) size_ *= 2;
		dat.resize(size_ * 2, 0);
	}

	void update(int pos, int x) {
		pos += size_;
		dat[pos] = x;
		while (pos >= 2) {
			pos >>= 1;
			dat[pos] = max(dat[pos * 2], dat[pos * 2 + 1]);
		}
	}

	int query_(int l, int r, int a, int b, int u) {
		if (l <= a && b <= r) return dat[u];
		if (r <= a || b <= l) return 0;
		int v1 = query_(l, r, a, (a + b) / 2, u * 2);
		int v2 = query_(l, r, (a + b) / 2, b, u * 2 + 1);
		return max(v1, v2);
	}

	int query(int l, int r) {
		return query_(l, r, 0, size_, 1);
	}
};

int N, C[1000009];
int M;
int A[1000009];
vector<int> G[1000009];
map<pair<int, int>, int> Map;

vector<int> solve(vector<int> V, vector<int> R) {
	Map.clear();
	for (int i = 1; i <= M; i++) G[i].clear();
	for (int i = 1; i <= M; i++) A[i] = 0;
	vector<int> Answer(M + 1, 0);

	// Init
	for (int i : V) A[i] += 1;
	for (int i : R) A[i] += 1;
	for (int i = 0; i < V.size(); i += 2) {
		int pa = V[i], pb = V[i + 1]; if (pa > pb) swap(pa, pb);
		Map[make_pair(pa, pb)] += 1;
		G[pa].push_back(pb);
		G[pb].push_back(pa);
	}
	RangeMax Z; Z.init(M + 2);
	for (int i = 1; i <= M; i++) Z.update(i, A[i]);

	// First Check
	for (int i = 0; i < V.size(); i += 2) {
		int pa = V[i + 0];
		int pb = V[i + 1]; if (pa > pb) swap(pa, pb);
		int cost = A[pa] + A[pb] - Map[make_pair(pa, pb)];
		if (pa == pb) continue;
		Answer[pa] = max(Answer[pa], cost);
		Answer[pb] = max(Answer[pb], cost);
	}

	// Second Check
	for (int i = 1; i <= M; i++) {
		for (int j : G[i]) Z.update(j, -100000000);
		Z.update(i, -100000000);
		int ret = Z.query(1, M + 1);
		Answer[i] = max(Answer[i], A[i] + ret);
		Z.update(i, A[i]);
		for (int j : G[i]) Z.update(j, A[j]);
	}
	return Answer;
}

int main() {
	// Step 1. Input
	cin >> N >> M;
	for (int i = 1; i <= N; i++) cin >> C[i];
	if (M == 1) {
		cout << "0" << endl;
		return 0;
	}

	// Step 2. Solve
	vector<int> V1, V2;
	vector<int> R1, R2;
	for (int i = 1; i <= N - 1; i += 2) { V1.push_back(C[i]); V1.push_back(C[i + 1]); }
	for (int i = 2; i <= N - 1; i += 2) { V2.push_back(C[i]); V2.push_back(C[i + 1]); }
	if (N % 2 == 0) { R2.push_back(C[1]); R2.push_back(C[N]); }
	if (N % 2 == 1) { R1.push_back(C[N]); R2.push_back(C[1]); }
	vector<int> Answer1 = solve(V1, R1);
	vector<int> Answer2 = solve(V2, R2);

	// Output
	for (int i = 1; i <= M; i++) cout << N - max(Answer1[i], Answer2[i]) << endl;
	return 0;
}
accuracy: 1
time_ms: 2760
memory_kb: 124396
final_rank: 14

code_snippet: #include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
struct run {
    bool is_target;
    int L, R;
    int len() {
        return R - L;
    }
};
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> c_orig(n), ans(m + 1, lim<int>::max());
    cin >> c_orig;
    auto get_cost = [&](vector<int> c, int target, bool use_left) {
        vector<run> runs;
        for(int i = 0; i < n; i++) {
            bool is_target = c[i] == target;
            if(runs.empty() or runs.back().is_target != is_target) {
                runs.push_back({is_target, i, i + 1});
            } else {
                runs.back().R++;
            }
        }
        int run_adjust_cost = 0;
        for(int i = 1; i + 1 < runs.size(); i++) {
            if(runs[i].len() % 2 == 1) {
                if(i == 1 and use_left) {
                    runs[i - 1].R--;
                    runs[i].L--;
                    if(runs[i].is_target) {
                        c[runs[i].L] = target;
                    } else {
                        c[runs[i].L + 1] = target;
                    }
                } else if(runs[i].is_target) {
                    c[runs[i].R] = target;
                    runs[i].R++;
                    runs[i + 1].L++;
                } else {
                    runs[i].R--;
                    runs[i + 1].L--;
                    c[runs[i].R] = target;
                }
                run_adjust_cost++;
            }
        }
        map<int, int> counter;
        for(int x : c) {
            counter[x]++;
        }
        int max_nontarget = 0;
        for(auto [x, count] : counter) {
            if(x != target) {
                max_nontarget = max(max_nontarget, count);
            }
        }
        int nontarget_cost = n - counter[target] - max_nontarget;
        return run_adjust_cost + nontarget_cost;
    };
    for(int target = 1; target <= m; target++) {
        auto c = c_orig;
        auto c_rev = c_orig;
        reverse(c_rev.begin(), c_rev.end());
        cout << min({
            get_cost(c, target, false),
            get_cost(c_rev, target, false),
            get_cost(c, target, true),
            get_cost(c_rev, target, true),
        }) << endl;
    }
    return 0;
}
accuracy: 0.45588235294117646
time_ms: 60
memory_kb: 7036
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
struct run {
    bool is_target;
    int L, R;
    int len() {
        return R - L;
    }
};
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n, m;
    cin >> n >> m;
    vector<int> c_orig(n), ans(m + 1, lim<int>::max());
    cin >> c_orig;
    auto get_cost = [&](vector<int> c, int target, bool use_left) {
        vector<run> runs;
        for(int i = 0; i < n; i++) {
            bool is_target = c[i] == target;
            if(runs.empty() or runs.back().is_target != is_target) {
                runs.push_back({is_target, i, i + 1});
            } else {
                runs.back().R++;
            }
        }
        int run_adjust_cost = 0;
        for(int i = 1; i + 1 < runs.size(); i++) {
            if(runs[i].len() % 2 == 1) {
                if(i == 1 and runs[i].is_target and use_left) {
                    runs[i - 1].R--;
                    runs[i].L--;
                    c[runs[i].L] = target;
                } else if(runs[i].is_target) {
                    c[runs[i].R] = target;
                    runs[i].R++;
                    runs[i + 1].L++;
                } else {
                    runs[i].R--;
                    runs[i + 1].L--;
                    c[runs[i].R] = target;
                }
                run_adjust_cost++;
            }
        }
        map<int, int> counter;
        for(int x : c) {
            counter[x]++;
        }
        int max_nontarget = 0;
        for(auto [x, count] : counter) {
            if(x != target) {
                max_nontarget = max(max_nontarget, count);
            }
        }
        int nontarget_cost = n - counter[target] - max_nontarget;
        return run_adjust_cost + nontarget_cost;
    };
    for(int target = 1; target <= m; target++) {
        auto c = c_orig;
        auto c_rev = c_orig;
        reverse(c_rev.begin(), c_rev.end());
        cout << min({
            get_cost(c, target, false),
            get_cost(c_rev, target, false),
            get_cost(c, target, true),
            get_cost(c_rev, target, true),
        }) << endl;
    }
    return 0;
}
accuracy: 0.45588235294117646
time_ms: 60
memory_kb: 6956
final_rank: 18

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cctype>

#include <algorithm>
#include <unordered_map>
#include <random>
#include <bitset>
#include <queue>
#include <functional>
#include <set>
#include <map>
#include <vector>
#include <chrono>
#include <iostream>
#include <limits>
#include <numeric>

#define LOG(FMT...) fprintf(stderr, FMT)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int main() {
#ifdef LBT
    freopen("test.in", "r", stdin);
    int nol_cl = clock();
#endif

    int N, M;
    scanf("%d%d", &N, &M);
    vector<int> C(N), cnt(M);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &C[i]);
        ++cnt[--C[i]];
    }
    vector<vector<vector<int>>> G(2, vector<vector<int>>(M));
    vector<int> ans = cnt;
    for (int i = 1; i < N; ++i)
        if (C[i] != C[i - 1]) {
            G[i & 1][C[i]].push_back(C[i - 1]);
            G[i & 1][C[i - 1]].push_back(C[i]);
        }
    vector<vector<int>> adjAns(2, vector<int>(M));
    vector<int> ccnt(N + 1);
    for (int c : cnt) ++ccnt[c];
    int mx = *max_element(cnt.begin(), cnt.end());
    if (M > 1) {
        for (int t = 0; t <= 1; ++t) {
            for (int i = 0; i < M; ++i) {
                --ccnt[cnt[i]];
                for (int j : G[t][i]) {
                    --ccnt[cnt[j]--];
                    ++ccnt[cnt[j]];
                }

                // cerr << t << ' ' << i << ": "; for (int k = 0; k <= N; ++k) cerr << ccnt[k] << ' '; cerr <<
                // '\n';
                adjAns[t][i] = mx;
                while (!ccnt[adjAns[t][i]]) --adjAns[t][i];
                ++ccnt[cnt[i]];
                for (int j : G[t][i]) {
                    --ccnt[cnt[j]++];
                    ++ccnt[cnt[j]];
                }
            }
        }
    }
    for (int i = 1; i < N; ++i)
        if (C[i] != C[i - 1]) {
            ans[C[i]] = max(ans[C[i]], cnt[C[i]] + adjAns[!(i & 1)][C[i]]);
            ans[C[i - 1]] = max(ans[C[i - 1]], cnt[C[i - 1]] + adjAns[!(i & 1)][C[i - 1]]);
        }

    for (int i = 0; i < M; ++i) printf("%d\n", N - ans[i]);

#ifdef LBT
    LOG("Time: %dms\n", int((clock() - nol_cl) / (double)CLOCKS_PER_SEC * 1000));
#endif
    return 0;
}
accuracy: 1
time_ms: 780
memory_kb: 135488
final_rank: 8

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;
 
 
#define NUM 1000005
 
int W,M;
int input[NUM];
int number[NUM];
int BIT[NUM],ans[NUM];
vector<int> V[NUM];
 
int N;
int table[6*NUM];
 
void init(int first_N){
    while(N < first_N)N *= 2;
}
 
void update(int loc,int value){
    loc += N-1;
 
    table[loc] += value;
 
    if(N == 1)return;
 
    int parent = (loc-1)/2;
 
    while(true){
        table[parent] = max(table[2*parent+1],table[2*parent+2]);
 
        if(parent == 0)break;
        else{
            parent = (parent-1)/2;
        }
    }
}
 
int query(int search_left,int search_right,int node_id,int node_left,int node_right){
 
    if(search_right < node_left || search_left > node_right)return -BIG_NUM;
 
    if(search_left <= node_left && search_right >= node_right){
        return table[node_id];
    }
 
    int left_max = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
    int right_max = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);
 
    return max(left_max,right_max);
}
 
int main(){
 
    scanf("%d %d",&W,&M);
 
    if(M == 1){
 
        printf("0\n");
        return 0;
    }
 
    for(int i = 0; i < M; i++){
 
        number[i] = 0;
        ans[i] = BIG_NUM;
    }
 
    for(int i = 0; i < W; i++){
 
        scanf("%d",&input[i]);
        input[i]--;
        number[input[i]] += 1;
    }
 
    N = 1;
    init(M);
 
    int tmp;
 
    for(int start = 0; start <= 1; start++){
 
        for(int i = start; i+1 <= W-1; i += 2){
 
            V[input[i]].push_back(input[i+1]);
            V[input[i+1]].push_back(input[i]);
        }
 
        for(int i = 0; i <= 2*N-2; i++)table[i] = 0;
 
        for(int i = 0; i < M; i++){
            update(i,number[i]);
        }
 
        for(int i = 0; i < M; i++){
 
            for(int k = 0; k < V[i].size(); k++){
 
                update(V[i][k],-1);
            }
            tmp = max(query(0,i-1,0,0,N-1),query(i+1,M-1,0,0,N-1));
 
            ans[i] = min(ans[i],W-(number[i]+tmp));
 
            for(int k = 0; k < V[i].size(); k++){
 
                update(V[i][k],1);
            }
        }
 
        for(int i = 0; i < M; i++){
            V[i].clear();
        }
    }
 
    for(int i = 0; i < M; i++){
 
        printf("%d\n",ans[i]);
    }
 
    return 0;
}
accuracy: 1
time_ms: 1550
memory_kb: 77824
final_rank: 4

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
#include<unordered_map>
#include<stack>
#include<queue>
#include<iomanip>
#include<math.h>
#include<bitset>
#include<cassert>
#include<random>
#include<time.h>
#include<functional>
using namespace std;
using ll=long long;
using ld=long double;
using pint=pair<int,int>;
using pll=pair<ll,ll>;
#define MOD 1000000007LL
#define INF 1000000000LL
#define EPS 1e-10
#define FOR(i,n,m) for(ll i=n;i<(ll)m;i++)
#define REP(i,n) FOR(i,0,n)
#define DUMP(a) REP(d,a.size()){cout<<a[d];if(d!=a.size()-1)cout<<" ";else cout<<endl;}
#define ALL(v) v.begin(),v.end()
#define UNIQUE(v)  sort(ALL(v));v.erase(unique(ALL(v)),v.end());
#define pb push_back

template <typename T>
class SegTree {
private:
	int n;
	const function<T(T, T)> op;
	const T ie;
	vector<T> seq;

public:
	SegTree(int _n, function<T(T, T)> op, const T ie) : op(op), ie(ie) {
		n = 1;
		while(n < _n) n *= 2;
		seq.resize(2 * n - 1);
		for(int i = 0; i < 2 * n - 1; i++) seq[i] = ie;
	}

	void update(int k, const T e) {
		k += n - 1;
		seq[k] = e;
		while(k > 0) {
			k = (k - 1) / 2;
			seq[k] = op(seq[k * 2 + 1], seq[k * 2 + 2]);
		}
	}

	T get(int k) {
		k += n - 1;
		return seq[k];
	}

	T query(int a, int b, int k = 0, int l = 0, int r = -1) {
		if(r == -1) r = n;
		if(r <= a || b <= l) return ie;
		if(a <= l && r <= b) return seq[k];
		T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
		T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
		return op(vl, vr);
	}
};

int n, m;
vector<int> c;
vector<int> ans;

void solve(int parity) {
	vector<vector<ll>> p(m);
	SegTree<int> rMq(m, [] (int a, int b) { return max(a, b); }, 0);
	REP(i, n) {
		rMq.update(c[i], rMq.get(c[i]) + 1);
		p[c[i]].pb(c[i]);
	}
	for(int i = parity; i < n - 1; i += 2) {
		if(c[i] == c[i + 1]) continue;
		p[c[i]].pb(c[i + 1]);
		p[c[i + 1]].pb(c[i]);
	}
	REP(i, m) {
		int tmp = n - rMq.get(i);
		REP(j, p[i].size()) rMq.update(p[i][j], rMq.get(p[i][j]) - 1);
		tmp -= rMq.query(0, m);
		REP(j, p[i].size()) rMq.update(p[i][j], rMq.get(p[i][j]) + 1);
		ans[i] = min(ans[i], tmp);
	}
	return;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cin >> n >> m;
	c.resize(n); ans.assign(m, INF);
	REP(i, n) cin >> c[i]; REP(i, n) c[i]--;
	solve(0); solve(1);
	REP(i, m) cout << ans[i] << endl;
	return 0;
}

/* --------------------------------------- */
accuracy: 1
time_ms: 2930
memory_kb: 73460
final_rank: 9

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
#include<unordered_map>
#include<stack>
#include<queue>
#include<iomanip>
#include<math.h>
#include<bitset>
#include<cassert>
#include<random>
#include<time.h>
#include<functional>
using namespace std;
using ll=long long;
using ld=long double;
using pint=pair<int,int>;
using pll=pair<ll,ll>;
#define MOD 1000000007LL
#define INF 1000000000LL
#define EPS 1e-10
#define FOR(i,n,m) for(ll i=n;i<(ll)m;i++)
#define REP(i,n) FOR(i,0,n)
#define DUMP(a) REP(d,a.size()){cout<<a[d];if(d!=a.size()-1)cout<<" ";else cout<<endl;}
#define ALL(v) v.begin(),v.end()
#define UNIQUE(v)  sort(ALL(v));v.erase(unique(ALL(v)),v.end());
#define pb push_back

int n, m;
vector<int> c;
vector<int> ans;

void solve(int parity) {
	vector<int> cnt1(m, 0);
	vector<int> cnt2(n + 1, 0);
	int maxi = -1;
	vector<vector<ll>> p(m);
	REP(i, n) {
		cnt1[c[i]]++;
		p[c[i]].pb(c[i]);
	}
	REP(i, m) {
		cnt2[cnt1[i]]++;
		maxi = max(maxi, cnt1[i]);
	}
	for(int i = parity; i < n - 1; i += 2) {
		if(c[i] == c[i + 1]) continue;
		p[c[i]].pb(c[i + 1]);
		p[c[i + 1]].pb(c[i]);
	}
	REP(i, m) {
		int tmp1 = n - cnt1[i];
		REP(j, p[i].size()) {
			cnt2[cnt1[p[i][j]]]--;
			cnt2[cnt1[p[i][j]] - 1]++;
			cnt1[p[i][j]]--;
		}
		int tmp2 = maxi;
		while(cnt2[tmp2] == 0) tmp2--;
		ans[i] = min(ans[i], tmp1 - tmp2);
		REP(j, p[i].size()) {
			cnt2[cnt1[p[i][j]]]--;
			cnt2[cnt1[p[i][j]] + 1]++;
			cnt1[p[i][j]]++;
		}
	}
	return;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cin >> n >> m;
	c.resize(n); ans.assign(m, INF);
	REP(i, n) cin >> c[i]; REP(i, n) c[i]--;
	solve(0); solve(1);
	REP(i, m) cout << ans[i] << endl;
	return 0;
}

/* --------------------------------------- */
accuracy: 1
time_ms: 1940
memory_kb: 73096
final_rank: 7

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 1000005

int W,M;
int input[NUM];
int number[NUM];
int BIT[NUM],ans[NUM];
vector<int> V[NUM];

int N;
int table[6*NUM];

void init(int first_N){
	while(N < first_N)N *= 2;
}

void update(int loc,int value){
	loc += N-1;

	table[loc] += value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		table[parent] = max(table[2*parent+1],table[2*parent+2]);

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}

int query(int search_left,int search_right,int node_id,int node_left,int node_right){

	if(search_right < node_left || search_left > node_right)return -BIG_NUM;

	if(search_left <= node_left && search_right >= node_right){
		return table[node_id];
	}

	int left_max = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
	int right_max = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

	return max(left_max,right_max);
}

int main(){

	scanf("%d %d",&W,&M);

	if(M == 1){

		printf("0\n");
		return 0;
	}

	for(int i = 0; i < M; i++){

		number[i] = 0;
		ans[i] = BIG_NUM;
	}

	for(int i = 0; i < W; i++){

		scanf("%d",&input[i]);
		input[i]--;
		number[input[i]] += 1;
	}

	N = 1;
	init(M);

	int tmp;

	for(int start = 0; start <= 1; start++){

		for(int i = start; i+1 <= W-1; i += 2){

			V[input[i]].push_back(input[i+1]);
			V[input[i+1]].push_back(input[i]);
		}

		for(int i = 0; i <= 2*N-2; i++)table[i] = 0;

		for(int i = 0; i < M; i++){
			update(i,number[i]);
		}

		for(int i = 0; i < M; i++){

			for(int k = 0; k < V[i].size(); k++){

				update(V[i][k],-1);
			}
			tmp = max(query(0,i-1,0,0,N-1),query(i+1,M-1,0,0,N-1));

			ans[i] = min(ans[i],W-(number[i]+tmp));

			for(int k = 0; k < V[i].size(); k++){

				update(V[i][k],1);
			}
		}

		for(int i = 0; i < M; i++){
			V[i].clear();
		}
	}

	for(int i = 0; i < M; i++){

		printf("%d\n",ans[i]);
	}

	return 0;
}
accuracy: 1
time_ms: 1570
memory_kb: 77776
final_rank: 5

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100005

int W,M;
int input[NUM];
int number[NUM];
int BIT[NUM],ans[NUM];
vector<int> V[NUM];

int N;
int table[6*NUM];

void init(int first_N){
	while(N < first_N)N *= 2;
}

void update(int loc,int value){
	loc += N-1;

	table[loc] += value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		table[parent] = max(table[2*parent+1],table[2*parent+2]);

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}

int query(int search_left,int search_right,int node_id,int node_left,int node_right){

	if(search_right < node_left || search_left > node_right)return -BIG_NUM;

	if(search_left <= node_left && search_right >= node_right){
		return table[node_id];
	}

	int left_max = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
	int right_max = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

	return max(left_max,right_max);
}

int main(){

	scanf("%d %d",&W,&M);

	if(M == 1){

		printf("0\n");
		return 0;
	}

	for(int i = 0; i < M; i++){

		number[i] = 0;
		ans[i] = BIG_NUM;
	}

	for(int i = 0; i < W; i++){

		scanf("%d",&input[i]);
		input[i]--;
		number[input[i]] += 1;
	}

	N = 1;
	init(M);

	int tmp;

	for(int start = 0; start <= 1; start++){

		for(int i = start; i+1 <= W-1; i += 2){

			V[input[i]].push_back(input[i+1]);
			V[input[i+1]].push_back(input[i]);
		}

		for(int i = 0; i <= 2*N-2; i++)table[i] = 0;

		for(int i = 0; i < M; i++){
			update(i,number[i]);
		}

		for(int i = 0; i < M; i++){

			for(int k = 0; k < V[i].size(); k++){

				update(V[i][k],-1);
			}
			tmp = max(query(0,i-1,0,0,N-1),query(i+1,M-1,0,0,N-1));

			ans[i] = min(ans[i],W-(number[i]+tmp));

			for(int k = 0; k < V[i].size(); k++){

				update(V[i][k],1);
			}
		}

		for(int i = 0; i < M; i++){
			V[i].clear();
		}
	}

	for(int i = 0; i < M; i++){

		printf("%d\n",ans[i]);
	}

	return 0;
}
accuracy: 0.7352941176470589
time_ms: 10
memory_kb: 6448
final_rank: 17

code_snippet: //22:04 1:03
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#define lol(i,n) for(int i=0;i<n;i++)
#define mod 1000000007
typedef long long ll;

using namespace std;
#define N (1<<20)
ll n,m,a[N],cnt[N];
class RMQ{
private:
    ll dat[2*N];
    ll dfs(int l,int r,int a,int b,int k){
	if(l<=a&&b<=r)return dat[k];
	if(b<=l||r<=a)return 0;
	ll vl=dfs(l,r,a,(a+b)/2,k*2+1);
	ll vr=dfs(l,r,(a+b)/2,b,k*2+2);
	return max(vl,vr);
    }
public:
    void Init(){
	lol(i,2*N)dat[i]=0;
	lol(i,m)Update(i,cnt[i]);
    }
    void Update(int i,ll x){
	i+=N-1;dat[i]=x;
	while(i>0){
	    i=(i-1)/2;
	    dat[i]=max(dat[i*2+1],dat[i*2+2]);
	}
    }
    void Add(int i,ll x){
	Update(i,dat[i+N-1]+x);
    }
    ll Max(int l,int r){
	return dfs(l,r+1,0,N,0);
    }
};
vector<ll> v[N];
ll ans[N];
void Solve(){
    RMQ seg;seg.Init();
    lol(i,m){
	for(auto x:v[i])seg.Add(x,-1);
	ll res=0;
	res=max(res,seg.Max(0,i-1));
	res=max(res,seg.Max(i+1,m-1));
	ans[i]=max(ans[i],res+cnt[i]);
	for(auto x:v[i])seg.Add(x,1);
    }
}
int main(){
    cin>>n>>m;
    lol(i,m)cnt[i]=0,ans[i]=0;
    lol(i,n){scanf("%lld",&a[i]);a[i]--;cnt[a[i]]++;}
    for(int i=0;i+1<n;i+=2){
	ll x=i,y=i+1;
	v[a[x]].push_back(a[y]);
	v[a[y]].push_back(a[x]);
    }
    Solve();
    lol(i,m)v[i].clear();
    for(int i=1;i+1<n;i+=2){
	ll x=i,y=i+1;
	v[a[x]].push_back(a[y]);
	v[a[y]].push_back(a[x]);
    }
    Solve();
    lol(i,m){
	ans[i]=n-ans[i];
	printf("%lld\n",ans[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 1310
memory_kb: 98800
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N = 1'000'011;
int dels[N], s[N], save[N], collec[N], n, m;
vector<int> vals[N];
pair<int,int> pairs[N];

void optimize(int p) {
    for (int c = 0; c < m; c++) vals[c].clear();

    int ps = 0;
    for (int l = p, r = p + 1; r < n; l += 2, r += 2) {
        if (s[l] != s[r]) pairs[ps++] = {min(s[l], s[r]), max(s[l], s[r])};
    }

    sort(pairs, pairs + ps);
    for (int i = 0, j = 0, c1, c2; i < ps; i = j) {
        while (j < ps && pairs[i] == pairs[j]) j++;
        tie(c1, c2) = pairs[i];
        vals[c1].push_back(dels[c2]);
        vals[c2].push_back(dels[c1]);
        int curr = dels[c1] + dels[c2] - j + i;
        save[c1] = max(save[c1], curr);
        save[c2] = max(save[c2], curr);
    }

    for (int c = 0; c < m; c++) {
        vals[c].push_back(dels[c]);
        sort(vals[c].begin(), vals[c].end());
        int t = m;
        for (int u = vals[c].size() - 1; u >= 0 && collec[t] == vals[c][u]; u--) t--;
        save[c] = max(save[c], dels[c] + collec[t]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; dels[--s[i++]]++) scanf("%d", &s[i]);
    for (int i = 0; i <= m; i++) collec[i] = dels[i];
    sort(collec, collec + m + 1);
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", n - save[i]);
}
accuracy: 1
time_ms: 530
memory_kb: 77336
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N = 1'000'011;
int dels[N], s[N], save[N], collec[N], n, m;
vector<int> vals[N];
pair<int,int> pairs[N];

void optimize(int p) {
    for (int c = 0; c < m; c++) vals[c].clear();

    int ps = 0;
    for (int l = p, r = p + 1; r < n; l += 2, r += 2) {
        if (s[l] != s[r]) pairs[ps++] = {min(s[l], s[r]), max(s[l], s[r])};
    }

    sort(pairs, pairs + ps);
    for (int i = 0, j = 0, c1, c2; i < ps; i = j) {
        while (j < ps && pairs[i] == pairs[j]) j++;
        tie(c1, c2) = pairs[i];
        vals[c1].push_back(dels[c2]);
        vals[c2].push_back(dels[c1]);
        int curr = dels[c1] + dels[c2] - j + i;
        save[c1] = max(save[c1], curr);
        save[c2] = max(save[c2], curr);
    }

    for (int c1 = 0; c1 < m; c1++) {
        vals[c1].push_back(dels[c1]);
        sort(vals[c1].begin(), vals[c1].end());
        int t = m;
        for (int u = vals[c1].size() - 1; u >= 0 && collec[t] == vals[c1][u]; u--) t--;
        save[c1] = max(save[c1], dels[c1] + collec[t]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; dels[--s[i++]]++) scanf("%d", &s[i]);
    for (int i = 0; i <= m; i++) collec[i] = dels[i];
    sort(collec, collec + m + 1);
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", n - save[i]);
}
accuracy: 1
time_ms: 530
memory_kb: 77480
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N = 1'000'011;
int dels[N], s[N], save[N];
vector<int> partners[N];
multiset<int> collec;
int n, m;

void optimize(int p) {
    for (int c = 0; c < m; c++) partners[c].clear();

    map<pair<int,int>,int> pairs;
    for (int l = p, r = p + 1; r < n; l += 2, r += 2) {
        if (s[l] != s[r]) pairs[{min(s[l], s[r]), max(s[l], s[r])}]++;
    }

    for (auto it : pairs) {
        int c1, c2;
        tie(c1, c2) = it.first;
        partners[c1].push_back(c2);
        partners[c2].push_back(c1);
        int curr = dels[c1] + dels[c2] - it.second;
        save[c1] = max(save[c1], curr);
        save[c2] = max(save[c2], curr);
    }
    pairs.clear();

    for (int c1 = 0; c1 < m; c1++) {
        partners[c1].push_back(c1);
        for (int c2 : partners[c1]) collec.erase(collec.find(dels[c2]));
        save[c1] = max(save[c1], dels[c1] + *collec.rbegin());
        for (int c2 : partners[c1]) collec.insert(dels[c2]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; dels[--s[i++]]++) scanf("%d", &s[i]);
    collec = multiset<int>(dels, dels + m + 1);
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", n - save[i]);
}
accuracy: 1
time_ms: 2470
memory_kb: 147720
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N = 1'000'011;
const int INF = 1<<29;
int dels[N], s[N], ans[N];
vector<int> partners[N];
multiset<int> collec;
int n, m;

void optimize(int p) {
    for (int c = 0; c < m; c++) partners[c].clear();

    map<pair<int,int>,int> pairs;
    for (int l = p, r = p + 1; r < n; l += 2, r += 2) {
        if (s[l] != s[r]) pairs[{min(s[l], s[r]), max(s[l], s[r])}]++;
    }

    for (auto it : pairs) {
        int c1, c2;
        tie(c1, c2) = it.first;
        partners[c1].push_back(c2);
        partners[c2].push_back(c1);
        int curr = dels[c1] + dels[c2] + it.second;
        ans[c1] = min(ans[c1], curr);
        ans[c2] = min(ans[c2], curr);
    }
    pairs.clear();

    for (int c1 = 0; c1 < m; c1++) {
        partners[c1].push_back(c1);
        for (int c2 : partners[c1]) collec.erase(collec.find(dels[c2]));
        ans[c1] = min(ans[c1], dels[c1] + *collec.begin());
        for (int c2 : partners[c1]) collec.insert(dels[c2]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int c = 0; c < m; c++) ans[c] = INF;
    for (int i = 0; i < n; i++) {
        scanf("%d", &s[i]);
        dels[--s[i]]--;
    }
    collec = multiset<int>(dels, dels + m + 1);
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", ans[i] + n);
}
accuracy: 1
time_ms: 2380
memory_kb: 147772
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int N = 1'000'011;
const int INF = 1<<29;
int dels[N], s[N], ans[N];
vector<int> partners[N];
int n, m;

void optimize(int p) {
    for (int c = 0; c < m; c++) {
        dels[c] = 0;
        partners[c].clear();
        partners[c].push_back(c);
    }
    int gs = 1;
    for (int i = 1; i < n; i++) if (i % 2 == p) gs++;
    for (int i = 0; i < n; i++) dels[s[i]]--;

    map<pair<int,int>,int> pairs;
    for (int gi = 0; gi < gs; gi++) {
        int li = max(0, 2*gi - p), ri = min(n - 1, 2*gi - p + 1);
        if (s[li] != s[ri]) pairs[{min(s[li], s[ri]), max(s[li], s[ri])}]++;
    }

    for (auto it : pairs) {
        int c1, c2;
        tie(c1, c2) = it.first;
        partners[c1].push_back(c2);
        partners[c2].push_back(c1);
        int curr = dels[c1] + dels[c2] + it.second;
        ans[c1] = min(ans[c1], curr);
        ans[c2] = min(ans[c2], curr);
    }
    pairs.clear();

    multiset<int> collec(dels, dels + m);
    collec.insert(0);
    for (int c1 = 0; c1 < m; c1++) {
        for (int c2 : partners[c1]) collec.erase(collec.find(dels[c2]));
        ans[c1] = min(ans[c1], dels[c1] + *collec.begin());
        for (int c2 : partners[c1]) collec.insert(dels[c2]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int c = 0; c < m; c++) ans[c] = INF;
    for (int i = 0; i < n; i++) {
        scanf("%d", &s[i]);
        s[i]--;
    }
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", ans[i] + n);
}
accuracy: 1
time_ms: 2540
memory_kb: 116432
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T>
inline void sort_uniq(vector<T>& vec) {
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
}

const int N = 1'000'011;
const int INF = 1<<29;
int dels[N], s[N], ans[N];
vector<int> partners[N];
int n, m;

void optimize(int p) {
    for (int c = 0; c < m; c++) {
        dels[c] = 0;
        partners[c].clear();
        partners[c].push_back(c);
    }
    int gs = 1;
    for (int i = 1; i < n; i++) if (i % 2 == p) gs++;
    for (int i = 0; i < n; i++) dels[s[i]]--;

    map<pair<int,int>,int> pairs;
    for (int gi = 0; gi < gs; gi++) {
        int li = max(0, 2*gi - p), ri = min(n - 1, 2*gi - p + 1);
        if (s[li] != s[ri]) pairs[{min(s[li], s[ri]), max(s[li], s[ri])}]++;
    }

    for (auto it : pairs) {
        int c1, c2;
        tie(c1, c2) = it.first;
        partners[c1].push_back(c2);
        partners[c2].push_back(c1);
        int curr = dels[c1] + dels[c2] + it.second;
        ans[c1] = min(ans[c1], curr);
        ans[c2] = min(ans[c2], curr);
    }
    pairs.clear();

    multiset<int> collec(dels, dels + m);
    collec.insert(0);
    for (int c1 = 0; c1 < m; c1++) {
        sort_uniq(partners[c1]);
        for (int c2 : partners[c1]) collec.erase(collec.find(dels[c2]));
        ans[c1] = min(ans[c1], dels[c1] + *collec.begin());
        for (int c2 : partners[c1]) collec.insert(dels[c2]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int c = 0; c < m; c++) ans[c] = INF;
    for (int i = 0; i < n; i++) {
        scanf("%d", &s[i]);
        s[i]--;
    }
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", ans[i] + n);
}
accuracy: 1
time_ms: 2620
memory_kb: 116540
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T>
inline void sort_uniq(vector<T>& vec) {
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
}

const int N = 1'000'011;
const int INF = 1<<29;
int coops[N], s[N], ans[N];
vector<int> partners[N];
bool appear[N];
int n, m;

void optimize(int p) {
    for (int c = 0; c < m; c++) {
        coops[c] = 0;
        partners[c].clear();
        partners[c].push_back(c);
    }
    int gs = 1;
    for (int i = 1; i < n; i++) if (i % 2 == p) gs++;

    map<pair<int,int>,int> fullgroups;
    for (int gi = 0; gi < gs; gi++) {
        int li = max(0, 2*gi - p), ri = min(n - 1, 2*gi - p + 1);
        coops[s[li]]--;
        if (li != ri) coops[s[ri]]--;
        if (s[li] != s[ri]) {
            fullgroups[{min(s[li], s[ri]), max(s[li], s[ri])}]++;
        }
    }

    for (auto it : fullgroups) {
        int c1, c2;
        tie(c1, c2) = it.first;
        partners[c1].push_back(c2);
        partners[c2].push_back(c1);
        int curr = coops[c1] + coops[c2] + it.second;
        ans[c1] = min(ans[c1], curr);
        ans[c2] = min(ans[c2], curr);
    }
    fullgroups.clear();

    multiset<int> collec(coops, coops + m);
    for (int c1 = 0; c1 < m; c1++) {
        sort_uniq(partners[c1]);
        ans[c1] = min(ans[c1], coops[c1]);
        for (int c2 : partners[c1]) collec.erase(collec.find(coops[c2]));
        if (!collec.empty()) ans[c1] = min(ans[c1], coops[c1] + *collec.begin());
        for (int c2 : partners[c1]) collec.insert(coops[c2]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int c = 0; c < m; c++) ans[c] = INF;
    for (int i = 0; i < n; i++) {
        scanf("%d", &s[i]);
        s[i]--;
    }
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", ans[i] + n);
}
accuracy: 1
time_ms: 2570
memory_kb: 116512
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T>
inline void sort_uniq(vector<T>& vec) {
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
}

const int N = 1'000'011;
const int INF = 1<<29;
int coops[N], s[N], ans[N];
vector<int> partners[N];
bool appear[N];
int n, m;

void optimize(int p) {
    for (int c = 0; c < m; c++) {
        coops[c] = 0;
        partners[c].clear();
        partners[c].push_back(c);
    }
    int gs = 1;
    for (int i = 1; i < n; i++) if (i % 2 == p) gs++;

    map<pair<int,int>,int> fullgroups;
    for (int gi = 0; gi < gs; gi++) {
        int li = max(0, 2*gi - p), ri = min(n - 1, 2*gi - p + 1);
        coops[s[li]]--;
        if (li != ri) coops[s[ri]]--;
        if (s[li] != s[ri]) {
            fullgroups[{min(s[li], s[ri]), max(s[li], s[ri])}]++;
        }
    }

    for (auto it : fullgroups) {
        int c1, c2;
        tie(c1, c2) = it.first;
        partners[c1].push_back(c2);
        partners[c2].push_back(c1);
        int curr = coops[c1] + coops[c2] + it.second;
        ans[c1] = min(ans[c1], curr);
        ans[c2] = min(ans[c2], curr);
    }
    fullgroups.clear();

    multiset<int> collec(coops, coops + m);
    for (int c1 = 0; c1 < m; c1++) {
        sort_uniq(partners[c1]);
        for (int c2 : partners[c1]) collec.erase(collec.find(coops[c2]));
        if (!collec.empty()) ans[c1] = min(ans[c1], coops[c1] + *collec.begin());
        for (int c2 : partners[c1]) collec.insert(coops[c2]);
    }
}

int main() {
    scanf("%d%d", &n, &m);
    for (int c = 0; c < m; c++) ans[c] = INF;
    for (int i = 0; i < n; i++) {
        scanf("%d", &s[i]);
        s[i]--;
    }
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) printf("%d\n", ans[i] + n);
}
accuracy: 0.35294117647058826
time_ms: 10
memory_kb: 26708
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
template<class T>
inline void sort_uniq(vector<T>& vec) {
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
}

const int N = 1'000'011;
const int INF = 1<<29;

int groupswith[N], coops[N];
vector<int> partners[N];
bool appear[N];
int s[N], ans[N];
int n, m;

void optimize(int p) {
    for (int c = 0; c < m; c++) {
        groupswith[c] = coops[c] = 0;
        partners[c].clear();
        partners[c].push_back(c);
    }
    int gs = 1;
    for (int i = 1; i < n; i++) if (i % 2 == p) gs++;

    map<pair<int,int>,int> fullgroups;
    for (int gi = 0; gi < gs; gi++) {
        int li = max(0, 2*gi - p), ri = min(n - 1, 2*gi - p + 1);
        groupswith[s[li]]++;
        coops[s[li]]--;
        if (li != ri) coops[s[ri]]--;
        if (s[li] != s[ri]) {
            groupswith[s[ri]]++;
            fullgroups[{min(s[li], s[ri]), max(s[li], s[ri])}]++;
        }
    }

    int best0 = INF;
    for (int c = 0; c < m; c++) best0 = min(best0, coops[c] + (gs == groupswith[c]));
    for (int c = 0; c < m; c++) ans[c] = min(ans[c], min(coops[c], best0));

    for (auto it : fullgroups) {
        int c1, c2;
        tie(c1, c2) = it.first;
        partners[c1].push_back(c2);
        partners[c2].push_back(c1);
        int curr = coops[c1] + coops[c2] + it.second;
        ans[c1] = min(ans[c1], curr);
        ans[c2] = min(ans[c2], curr);
    }
    fullgroups.clear();

    multiset<int> collec(coops, coops + m);

    for (int c1 = 0; c1 < m; c1++) {
        if (!appear[c1]) continue;
        sort_uniq(partners[c1]);
        for (int c2 : partners[c1]) collec.erase(collec.find(coops[c2]));
        if (!collec.empty()) ans[c1] = min(ans[c1], coops[c1] + *collec.begin());
        for (int c2 : partners[c1]) collec.insert(coops[c2]);
    }
}

void solve() {
    if (scanf("%d%d", &n, &m) != 2) exit(0);
    for (int c = 0; c < m; c++) {
        appear[c] = false;
        ans[c] = INF;
    }
    for (int i = 0; i < n; i++) {
        scanf("%d", &s[i]);
        appear[--s[i]] = true;
    }
    optimize(0);
    optimize(1);
    for (int i = 0; i < m; i++) {
        printf("%d\n", ans[i] + n);
    }
}

int main() {
    while (true) solve();
}
accuracy: 1
time_ms: 2660
memory_kb: 121424
final_rank: 13