题意:选择最长的连续子序列满足要么一个数字出现的次数为零,要么出现的次数大于K
根据题解,我们可以枚举右端点,然后依次维护x[i]的值,x[i]意思为在i这个地方有多少个数字满足要求,若x[i]==C,那么其满足条件,那么我们可以选择最小的满足的下标i为答案,用线段树维护这个值即可。

#include<iostream>
#include<string.h>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 1e5 + 5;
vector<int> tq[N];
int l[N], r[N];
int q[N], num[N];
bool f[N];
struct node {
    int l, r, mx, mi;
    int rz;
}t[N << 2];
int n, c, k;

void pushup(int x) {
    t[x].mx = max(t[x << 1].mx, t[x << 1 | 1].mx);
    t[x].mi = min(t[x << 1].mi, t[x << 1 | 1].mi);
}

void down(int x) {
    if (!t[x].rz) return;
    t[x << 1].mi += t[x].rz;
    t[x << 1 | 1].mi += t[x].rz;
    t[x << 1].mx += t[x].rz;
    t[x << 1 | 1].mx += t[x].rz;
    t[x << 1].rz += t[x].rz;
    t[x << 1 | 1].rz += t[x].rz;
    t[x].rz = 0;
}
void bulit(int l, int r, int rt) {
    t[rt].l = l, t[rt].r = r;
    t[rt].rz = 0;
    if (l == r) {
        t[rt].mi = t[rt].mx = c;
        return;
    }
    int mid = (l + r) >> 1;
    bulit(l, mid, rt << 1);
    bulit(mid + 1, r, rt << 1 | 1);
    pushup(rt);
}

void add(int l, int r, int x,int rt) {
    if (l > r) return;
    if (l <= t[rt].l&& t[rt].r <= r) {
        t[rt].mx += x;
        t[rt].mi += x;
        t[rt].rz += x;
        return;
    }
    down(rt);
    int mid = (t[rt].l + t[rt].r) >> 1;
    if (l <= mid) add(l, r, x, rt << 1);
    if (mid < r) add(l, r, x, rt << 1 | 1);
    pushup(rt);
}
int cnt;
void query(int l, int r, int rt) {
    //printf("%d %d %d\n", rt, t[rt].mx, t[rt].mi);
    if (l <= t[rt].l&& r >= t[rt].r) {
        if (t[rt].mi == t[rt].mx && t[rt].mx == c) {
            cnt = min(cnt, t[rt].l);
            return;
        }
        else if (t[rt].l == t[rt].r ) return;
    }
    down(rt);
    int mid = (t[rt].l + t[rt].r) >> 1;
    if (l <= mid && t[rt << 1].mx == c) query(l, r, rt << 1);
    if (mid < r && t[rt << 1 | 1].mx == c) query(l, r, rt << 1 | 1); 
    pushup(rt);
}

int main() {
    while (~scanf("%d%d%d", &n, &c, &k)) {
        for (int i = 1; i <= n; i++) scanf("%d", &q[i]);
        if (k <= 1) {
            printf("%d\n", n);
            continue;
        }
        for (int i = 0; i < N; i++) tq[i].clear();
        for (int i = 1; i <= n; i++) tq[q[i]].push_back(i);
        for (int i = 1; i <= c; i++) {
            l[i] = r[i] = 0;
            f[i] = false;
            num[i] = 0;
        }
        bulit(1, n, 1);
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            if (!f[q[i]]) {
                add(r[q[i]] + 1, i, -1, 1);
                //printf("%d %d\n", r[q[i]], i);
                r[q[i]] = i;
                if (num[q[i]] == 0) l[q[i]] = i;
                num[q[i]]++;
                if (num[q[i]] == k) {
                    f[q[i]] = true;
                    add(1, l[q[i]], 1, 1);
                }
                cnt = n + 1;
                query(1, i, 1);
            }
            else {
                add(r[q[i]] + 1, i, -1, 1);
                r[q[i]] = i;
                int v = lower_bound(tq[q[i]].begin(), tq[q[i]].end(), l[q[i]]) - tq[q[i]].begin();
                v = tq[q[i]][v + 1];
                add(l[q[i]] + 1, v, 1, 1);
                l[q[i]] = v;
                cnt = n + 1;
                query(1, i, 1);
            }
            //cout << num[q[i]] << endl;
            ans = max(i - cnt + 1,ans);
        }
        cout << ans << endl;
    }
    return 0;
}