--- 这里是 cjiaw 的小窝(●'◡'●) ---

正在玩命加载中......

CF_2149_E. Hidden Knowledge of the Ancients

题目链接:Problem - E - Codeforces


题目大意:

寻找长度为 n数组 中有多少区间满足以下条件:

  • 区间内包括恰好  个不同整数
  • 区间长度在 之间

滑动窗口,容斥原理

根据容斥原理,恰好k个 = 最多k个 - 最多(k-1)

计算以窗口的右端点作为结束点时有多少个符合 区间长度在 之间 的条件


代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define  mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;

const int N = 200086, mod = 998244353;

int n, k, l, r;
int a[N];

int check(int x) {

    int res = 0;
    map<int, int> mp;
    
    int cnt = 0;
    for (int ll = 1, rr = 1; rr <= n; rr++) {
        if (!mp[a[rr]]) cnt++;
        mp[a[rr]]++;
        
        while (cnt > x) {
            if (!--mp[a[ll++]]) cnt--;
        }
        
        res += max(0ll, rr - l + 1 - max(rr - r + 1, ll) +1);
    }
    
    return res;
}

void solve() {

    cin >> n >> k >> l >> r;
    for (int i = 1; i <= n; i++) cin >> a[i];
    
    cout << check(k) - check(k - 1) << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    
    int T = 1;
    cin >> T;
    while (T--) solve();
    
    return 0;
}

 

posted @ 2025-10-17 22:15  cjiaw  阅读(0)  评论(0)    收藏  举报