• cf--TV Subscriptions (Hard Version)


    time limit per test:2 seconds
    memory limit per test:256 megabytes
    input:standard input
    output:standard output

    The only difference between easy and hard versions is constraints.

    The BerTV channel every day broadcasts one episode of one of the k TV shows. You know the schedule for the next n days: a sequence of integers a1,a2,…,an (1≤ai≤k), where ai is the show, the episode of which will be shown in i-th day.

    The subscription to the show is bought for the entire show (i.e. for all its episodes), for each show the subscription is bought separately.

    How many minimum subscriptions do you need to buy in order to have the opportunity to watch episodes of purchased shows d (1≤d≤n) days in a row? In other words, you want to buy the minimum number of TV shows so that there is some segment of d consecutive days in which all episodes belong to the purchased shows.

    Input
    The first line contains an integer t (1≤t≤10000) — the number of test cases in the input. Then t test case descriptions follow.

    The first line of each test case contains three integers n,k and d (1≤n≤2⋅105, 1≤k≤106, 1≤d≤n). The second line contains n integers a1,a2,…,an (1≤ai≤k), where ai is the show that is broadcasted on the i-th day.

    It is guaranteed that the sum of the values ​​of n for all test cases in the input does not exceed 2⋅105.

    Output
    Print t integers — the answers to the test cases in the input in the order they follow. The answer to a test case is the minimum number of TV shows for which you need to purchase a subscription so that you can watch episodes of the purchased TV shows on BerTV for d consecutive days. Please note that it is permissible that you will be able to watch more than d days in a row.

    Example
    input

    4
    5 2 2
    1 2 1 2 1
    9 3 3
    3 3 3 2 2 2 1 1 1
    4 10 4
    10 8 6 4
    16 9 8
    3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3
    

    output

    2
    1
    4
    5
    

    Note
    In the first test case to have an opportunity to watch shows for two consecutive days, you need to buy a subscription on show 1 and on show 2. So the answer is two.

    In the second test case, you can buy a subscription to any show because for each show you can find a segment of three consecutive days, consisting only of episodes of this show.

    In the third test case in the unique segment of four days, you have four different shows, so you need to buy a subscription to all these four shows.

    In the fourth test case, you can buy subscriptions to shows 3,5,7,8,9, and you will be able to watch shows for the last eight days.

    思路:
    刚开始看到这个题目时,想到了莫队的分块统计+埃筛,写完了一直在debug,然后看了学长的代码明白过来了,原来是这样做
    t组输入样例,
    n表示n个数,k表示着n个数中的最大值,d表示连续的几个数中不同的数字个数(不重复的数字个数)
    我可以表示出第一个区间里符合题意的树,然后依次往下移动,知道所有的都找完

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <set>
    using namespace std;
    const int maxn = 1e6 + 10;
    set<int> s;
    map<int,int> mp;
    int a[maxn];
    int t,n,k,d;
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        cin >> t;
        while(t--){
            mp.clear();
            s.clear();
            cin >> n >> k >> d;
            for(int i = 1; i <= n; i++)
                cin >> a[i];
    
            for(int i = 1; i <= d; i++){
                mp[a[i]]++;
                s.insert(a[i]);
            }
            //左右边界找到,然后依次下移,利用的map的计数和set的去重
            int l = 1, r = d,ans = s.size();
            while(r < n){//等于不成立,因为里面有r++
                mp[a[l]]--;//我是想要右移
                if(mp[a[l]]==0)//没有的话,就可以删除
                    s.erase(a[l]);
                l++;
                r++;
                s.insert(a[r]);//向右移动,插入
                mp[a[r]]++;//这一步刚开时忘记写,
                if(s.size() < ans)
                    ans = s.size();
            }
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    C++输入cout与输出cin
    golang学习笔记
    vscode环境配置
    golang 微框架 gin
    git go使用socket5代理
    go包管理工具glide
    collectd的python插件(redis)
    zookeeper & kafka 集群
    redis复制集(sentinel)
    python加解密
  • 原文地址:https://www.cnblogs.com/xcfxcf/p/12301622.html
Copyright © 2020-2023  润新知