• CodeForces813E:Army Creation (主席树---上一题的加强版)


    As you might remember from our previous rounds, Vova really likes computer games. Now he is playing a strategy game known as Rage of Empires.

    In the game Vova can hire n different warriors; ith warrior has the type ai. Vova wants to create a balanced army hiring some subset of warriors. An army is called balanced if for each type of warrior present in the game there are not more than k warriors of this type in the army. Of course, Vova wants his army to be as large as possible.

    To make things more complicated, Vova has to consider q different plans of creating his army. ith plan allows him to hire only warriors whose numbers are not less than li and not greater than ri.

    Help Vova to determine the largest size of a balanced army for each plan.

    Be aware that the plans are given in a modified way. See input section for details.

    Input

    The first line contains two integers n and k (1 ≤ n, k ≤ 100000).

    The second line contains n integers a1a2, ... an (1 ≤ ai ≤ 100000).

    The third line contains one integer q (1 ≤ q ≤ 100000).

    Then q lines follow. ith line contains two numbers xi and yi which represent ith plan (1 ≤ xi, yi ≤ n).

    You have to keep track of the answer to the last plan (let's call it last). In the beginning last = 0. Then to restore values of li and ri for the ith plan, you have to do the following:

    1. li = ((xi + lastmod n) + 1;
    2. ri = ((yi + lastmod n) + 1;
    3. If li > ri, swap li and ri.

    Output

    Print q numbers. ith number must be equal to the maximum size of a balanced army when considering ith plan.

    Example

    Input
    6 2
    1 1 1 2 2 2
    5
    1 6
    4 3
    1 1
    2 6
    2 6
    Output
    2
    4
    1
    3
    2

    Note

    In the first example the real plans are:

    1. 1 2
    2. 1 6
    3. 6 6
    4. 2 4
    5. 4 6

    题意:给定N个数,以及Q个询问,每个询问给出L和R,现在问在这个区间选最多的数,使得每个数出现次数不能大于K。

    思路:有了上一题的积累,这题就是一眼题了。上一题相当于的K=1。此题,我们任然算前缀的贡献,[1,i]区间建立在[1,i-1]基础上,如果前缀[1,i]里a[i]出现的次数大于等于K,我们删去最前面那一个的贡献1,加上i的贡献1,保证每个前缀不同数的贡献小于等于K。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=200010;
    struct node{ 
        int val,l,r; 
        node() {} 
        node(int L,int R,int V):l(L),r(R),val(V){}
    }s[maxn*20];
    int rt[maxn],cnt,ans;
    queue<int>q[maxn];
    void insert(int &now,int pre,int L,int R,int pos,int val)
    {
        s[now=++cnt]=node(s[pre].l,s[pre].r,s[pre].val+val);  //先假设都等 
        if(L==R) return ;
        int Mid=(L+R)>>1;
        if(pos<=Mid) insert(s[now].l,s[pre].l,L,Mid,pos,val); //这里再把不等的改掉 
        else insert(s[now].r,s[pre].r,Mid+1,R,pos,val);
    }
    int query(int now,int pos,int L,int R)
    {
        if(L==R) return s[now].val;
        int Mid=(L+R)>>1;
        if(pos<=Mid) return query(s[now].l,pos,L,Mid)+s[s[now].r].val;
        return query(s[now].r,pos,Mid+1,R);
    }
    int main()
    {
        int N,Q,K,x,y,i;
        scanf("%d%d",&N,&K);
        for(i=1;i<=N;i++){
            scanf("%d",&x);
            if(q[x].size()<K) insert(rt[i],rt[i-1],1,N,i,1);
            else {
                int last=q[x].front(); q[x].pop();
                insert(y,rt[i-1],1,N,last,-1);
                insert(rt[i],y,1,N,i,1);
            }
            q[x].push(i);
        }
        scanf("%d",&Q);
        while(Q--){
            scanf("%d%d",&x,&y);
            x=(x+ans)%N+1;
            y=(y+ans)%N+1;
            if(x>y) swap(x,y);
            ans=query(rt[y],x,1,N);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    快速读取txt文档
    ASP.NET中缓存非SQLServer数据库数据
    查看linq to sql 生成的sql 语句
    跟树有关的数据结构学习系列之概览
    Linux安装软件包时的“依赖关系树”算法(C#)
    Go调度器介绍和容易忽视的问题
    搞懂Go垃圾回收
    Go“一个包含nil指针的接口不是nil接口”踩坑
    Go slice:切片的“陷阱”和本质
    C#调用ODBC连接SQL Server数据库的存储过程
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9105426.html
Copyright © 2020-2023  润新知