F. Machine Learning 带修端点莫队

F. Machine Learning

time limit per test

4 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

You come home and fell some unpleasant smell. Where is it coming from?

You are given an array a. You have to answer the following queries:

  1. You are given two integers l and r. Let ci be the number of occurrences of i in al: r, where al: r is the subarray of a from l-th element to r-th inclusive. Find the Mex of {c0, c1, ..., c109}
  2. You are given two integers p to x. Change ap to x.

The Mex of a multiset of numbers is the smallest non-negative integer not in the set.

Note that in this problem all elements of a are positive, which means that c0 = 0 and 0 is never the answer for the query of the second type.

Input

The first line of input contains two integers n and q (1 ≤ n, q ≤ 100 000) — the length of the array and the number of queries respectively.

The second line of input contains n integers — a1, a2, ..., an (1 ≤ ai ≤ 109).

Each of the next q lines describes a single query.

The first type of query is described by three integers ti = 1, li, ri, where 1 ≤ li ≤ ri ≤ n — the bounds of the subarray.

The second type of query is described by three integers ti = 2, pi, xi, where 1 ≤ pi ≤ n is the index of the element, which must be changed and 1 ≤ xi ≤ 109 is the new value.

Output

For each query of the first type output a single integer  — the Mex of {c0, c1, ..., c109}.

Example

Input

Copy

10 41 2 3 1 1 2 2 2 9 91 1 11 2 82 7 11 2 8

Output

#include<cstdio>
#include<cstring>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=2e5+88;
map<int,int>M;
int vis[N],num[N],a[N],b[N],now[N],ans[N],unit,l,r,t;
struct Query{
    int l,r,tim,id;
    bool operator < (const Query &A)const{
      return l/unit==A.l/unit?(r/unit==A.r/unit?tim<A.tim:r<A.r):l<A.l;
    }
}Q[N];
struct Change{
    int pos,x,y;
}C[N];
void modify(int x,int d){
    --vis[num[x]];num[x]+=d;++vis[num[x]];
}
void going(int T,int d){
    if(C[T].pos>=l&&C[T].pos<=r) modify(C[T].x,d),modify(C[T].y,-d);
    if(d==1) a[C[T].pos]=C[T].x;else a[C[T].pos]=C[T].y;
}
int calc(){
    for(int i=1;;++i) if(!vis[i]) return i;
}
int main(){
    int n,q,tot,op,cc=0,pp=0;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]),now[i]=b[i]=a[i];
    tot=n,unit=(int)pow(n,0.6666666);
    for(int i=1;i<=q;++i) {
        scanf("%d",&op);
        if(op==2){
        ++cc,scanf("%d%d",&C[cc].pos,&C[cc].x);
        C[cc].y=now[C[cc].pos],b[++tot]=now[C[cc].pos]=C[cc].x;
        }
        else {
        ++pp,scanf("%d%d",&Q[pp].l,&Q[pp].r);
        Q[pp].tim=cc,Q[pp].id=pp;
        }
    }
    sort(b+1,b+tot+1);
    tot=unique(b+1,b+tot+1)-b-1;
    for(int i=1;i<=tot;++i) M[b[i]]=i;
    for(int i=1;i<=n;++i) a[i]=M[a[i]];
    for(int i=1;i<=cc;++i) C[i].x=M[C[i].x],C[i].y=M[C[i].y];
    sort(Q+1,Q+pp+1);
    for(int i=1;i<=pp;++i) {
        while(t<Q[i].tim) going(t+1,1),++t;
        while(t>Q[i].tim) going(t,-1),--t;

        while(l<Q[i].l) modify(a[l],-1),++l;
        while(l>Q[i].l) modify(a[l-1],1),--l;
        while(r<Q[i].r) modify(a[r+1],1),++r;
        while(r>Q[i].r) modify(a[r],-1),--r;
        ans[Q[i].id]=calc();

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

2
3
2

莫队学习博客

原文地址:https://www.cnblogs.com/mfys/p/8519628.html

时间: 2024-11-09 11:05:19

F. Machine Learning 带修端点莫队的相关文章

带修改的莫队算法学习小记

简介 莫涛大神创造出的离线询问算法的带修改版. 算法基础:需要掌握莫队算法,会打暴搜(暴力). 一个叫莫的双端队列. 只支持单点修改 操作方法 普通的不带修改的莫队算法要把每个询问带上两个关键字排序,现在待修改的莫队算法要带上三个关键字排序. 初始操作 fo(i,1,m) { scanf("%s%d%d",s,&k,&l); if (s[0]=='Q')a[++tot].l=k,a[tot].r=l,a[tot].x=num,a[tot].p=tot; else d[+

bzoj 2120: 数颜色(带修改的莫队算法)

2120: 数颜色 Time Limit: 6 Sec  Memory Limit: 259 MB Submit: 2908  Solved: 1130 [Submit][Status][Discuss] Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P Col 把第P支画笔替换为颜色Col.为了满足墨墨的要求,你知道你需

BZOJ 2120: 数颜色 带修改的莫队算法 树状数组套主席树

https://www.lydsy.com/JudgeOnline/problem.php?id=2120 标题里是两种不同的解法. 带修改的莫队和普通莫队比多了个修改操作,影响不大,但是注意一下细节不要出现zz错误. 这道题修改的数量比较少可以写莫队,但是如果修改数量多或者是特别极限的数据大概是不行的吧. 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstrin

F. Machine Learning (带修改莫队)

https://codeforces.com/contest/940/problem/F 题意  给出n个数字,q个询问: 每次询问有两种类型,一种是询问区间,一种是单体修改: 询问区间是询问区间内最小的没用到的大于0的整数: 比如我有一串数字是 1 1 2 2 2 3    那么有两个1 三个2,一个3   出现次数分别有 两 三 一,  那么次数最小的没在区间内出现的是4: 对于这道题,除带修改莫队的模板之外,我们多加两个数组 vis cnt vis数组用来记录某个数出现的频率,cnt用来记

带修改的莫队

在学习了最基础的莫队后,我们会发现普通莫队并不资瓷修改操作啊!!!这就很尴尬,那么莫队就没办法修改吗,反正当时发明莫队的人是没有提到的,但是不要小瞧了智慧的OI人,不久就有人就提出了带修改莫队的想法. 如果你还没不知道莫队 点击这里!!! 其实刚知道莫队还可以资瓷修改时,我以为代码量会有质的飞越,但是学习后才发现原来不过如此,所以就别担心了... 首先还是来一道题 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1.

BZOJ 3052 WC2013 糖果公园 带修改树上莫队

题目大意:给定一棵树,每个点有一个颜色,提供两种操作: 1.询问两点间路径上的Σv[a[i]]*w[k],其中a[i]代表这个点的颜色,k表示这个点是这种颜色第k次出现 2.修改某个点的颜色 VfleaKing的题解见 http://vfleaking.blog.163.com/blog/static/174807634201311011201627/ 带修改莫队上树--如果不带修改就正常搞就好了 如果带修改的话,令块的大小为n^(2/3) 将询问排序时第一键值为左端点所在块,第二键值为右端点所

BZOJ 4129 Haruna’s Breakfast 带修改树上莫队+分块

题目大意:给定一棵树,每个点有一个非负点权,支持下列操作 1.修改某个点的点权 2.查询某条链上的mex 考虑链上不带修改的版本,我们可以用莫队+分块来搞(链接戳这里) 现在到了树上带修改,果断糖果公园 本来抱着逗比的心态写了一发结果1.4s过了 跟糖果公园的80s完全不成正比啊0.0 #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <

Codeforces Round #466 (Div. 2) F - Machine Learning

可以观察到,因为我们答案是通过MEX函数得到,那么假设,当前MEX的值是p,那么这时候一共有1+2+3+4...+p-1个与\(c_1\),\(c_2\),\(c_3\)...\(c_p-1\)相同,一共是p*(p-1)/2个数字,那么MEX值一定不超过\(\sqrt n\).故暴力能统计答案. 对于有修改的询问,我们采用待修改莫队,取块的大小为\(n^{\frac23}\). #include<iostream> #include<cstring> #include<alg

CF940F Machine Learning (带修改莫队)

题目链接 https://codeforces.com/contest/940/problem/F 题意 给出n个数字,q个询问: 每次询问有两种类型,一种是询问区间,一种是单体修改: 定义Ci为区间里数字 i 出现的次数,求Ci数组的mex #include<bits/stdc++.h> using namespace std; const int maxx = 2e5+10; struct qnode { int l,r,t,id; }e[maxx]; struct cnode { int