题目大意:一个数列若能在有限次数内删空,则称这个数列可以删空,一次删除操作定义如下:

记当前数列长度为$k$,则删掉数列中所有等于$k$的数。

现在有一个长度为$n$的数列$a$,有$m$次修改操作,为单点变值/整体增加或者减少$1$,问每次修改后,最少需要修改序列中多少个数,使得序列可以被删除。

数据范围:$n≤150000$。

我们首先考虑下最少需要修改的次数,我们设$b[i]$为数列$a$中填写了i的值得数量。

对于每一个$i$,我们可以用$b[i]$这么多数,覆盖区间$[i-b[i]+1,i]$。最终的答案就是未被覆盖的格子数量。

证明显然。

基于这个结论,我们就可以在$O(n)$的复杂度内求出一个序列$a$对应的答案,可以获得47分的好成绩。

在只有单点修改的情况下,我们发现我们可以用线段树做一下维护,就可以获得60分的好成绩。

我们发现,整体的$+1$或者$-1$,可以转化为查询的区间出现了移动,移动完查询区间后,我们更新一下两端的值即可。

这么搞就可以过掉这一题了。

时间复杂度:$O(n\log\ n)$。

 #include<bits/stdc++.h>
#define M (1<<19)
using namespace std; struct seg{int l,r,tag,minn,cnt;}a[M<<];
void pushup(int x){
a[x].minn=min(a[x<<].minn,a[x<<|].minn);
a[x].cnt=(a[x].minn==a[x<<].minn?a[x<<].cnt:)+(a[x].minn==a[x<<|].minn?a[x<<|].cnt:);
}
void upd(int x,int k){a[x].minn+=k; a[x].tag+=k;}
void pushdown(int x){if(a[x].tag) upd(x<<,a[x].tag),upd(x<<|,a[x].tag); a[x].tag=;} void build(int x,int l,int r){
a[x].l=l; a[x].r=r; if(l==r) return void(a[x].cnt=);
int mid=(l+r)>>;
build(x<<,l,mid); build(x<<|,mid+,r);
pushup(x);
}
void updata(int x,int l,int r,int k){
if(l<=a[x].l&&a[x].r<=r) return upd(x,k);
pushdown(x); int mid=(a[x].l+a[x].r)>>;
if(l<=mid) updata(x<<,l,r,k);
if(mid<r) updata(x<<|,l,r,k);
pushup(x);
}
void updata(int x,int id,int k){return updata(x,id,id,k);}
int query(int x,int l,int r){
if(a[x].minn>) return ;
if(l<=a[x].l&&a[x].r<=r) return a[x].cnt;
pushdown(x); int mid=(a[x].l+a[x].r)>>,cnt=;
if(l<=mid) cnt+=query(x<<,l,r);
if(mid<r) cnt+=query(x<<|,l,r);
return cnt;
} int num[M],n,q,m,orzorz[M*]={};
int *cnt=orzorz+M;
int main(){
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++) scanf("%d",num+i),cnt[num[i]]++;
int T=max(n,q),m=T+n+q+,move=;
build(,,m);
for(int i=;i<=n;i++) updata(,T+i-cnt[i]+,T+i,);
while(q--){
int p,x; scanf("%d%d",&p,&x);
if(p>){
x-=move;
if(num[p]+move>=&&num[p]+move<=n)
updata(,num[p]-cnt[num[p]]++T,-);
cnt[num[p]]--; num[p]=x; cnt[num[p]]++;
updata(,num[p]-cnt[num[p]]++T,);
}else{
if(x<) move--;
updata(,-move-cnt[-move]++T,-move+T,x);
updata(,n-move-cnt[n-move]++T,n-move+T,-x);
if(x>) move++;
}
printf("%d\n",query(,T-move+,T-move+n));
}
}

【BJOI2019】删数 线段树的更多相关文章

  1. [Luogu5324][BJOI2019]删数(线段树)

    CF风格题,先猜结论,记数列中i这个数共出现了cnt[i]次,那么所有区间[i-cnt[i]+1,i]的并集的补集大小就是答案. 于是我们只需要线段树维护每个位置是否被某个区间覆盖到即可,对于整体加减 ...

  2. [BJOI2019]删数(线段树)

    [BJOI2019]删数(线段树) 题面 洛谷 题解 按照值域我们把每个数的出现次数画成一根根的柱子,然后把柱子向左推导,\([1,n]\)中未被覆盖的区间长度就是答案. 于是问题变成了单点修改值,即 ...

  3. [BJOI2019] 删数 [dp转贪心结论+线段树]

    题面 传送门 思路 dp部分 以下称合法序列为原题面中可以删空的序列 这个是我在模拟考场上的思路 一开始我是觉得,这个首先可以写成一个dp的形式:$dp[i][j]$表示用$j$个数字填满了目标序列的 ...

  4. Luogu5324 BJOI2019删数(线段树)

    考虑无修改怎么做.对于1~n的每个数,若其存在,将最后一个放在其值的位置,剩余在其前面依次排列,答案即为值域1~n上没有数的位置个数.带修改显然记一下偏移量线段树改一改就好了. #include< ...

  5. luogu P5324 [BJOI2019]删数

    传送门 不如先考虑暴力,能删的序列首先有\(1,2,3...n\),还有就是升序排序后从后往前放数,第\(i\)位要么放\(i\),要么放\(i+1\)位置的数,例如\(1,2,4,4,5,6,9,9 ...

  6. 题解 洛谷 P5324 【[BJOI2019]删数】

    先考虑对于一个序列,能使其可以删空的的修改次数. 首先可以发现,序列的排列顺序是没有影响的,所以可以将所有数放到桶里来处理. 尝试对一个没有经过修改的可以删空的序列来进行删数,一开始删去所有的\(n\ ...

  7. Problem 1007 幸运数 线段树成段更新

    题目链接: 题目 Problem 1007 幸运数 Time Limit: 2000 mSec Memory Limit : 131072 KB 问题描述 皮特的幸运数是2和5.只由幸运数字2和5组成 ...

  8. [BJOI2019] 删数

    https://www.luogu.org/problemnew/show/P5324 题解 首先我们需要弄清这个答案是什么. 对于一个长度为n的序列,那么它先删的肯定是\(n\),删完之后它就会跳到 ...

  9. hdu 4417 区间内比h小的数 线段树

    题意求区间内比h小的数的个数 将所有的询问离线读入之后,按H从小到大排序.然后对于所有的结点也按从小到大排序,然后根据查询的H,将比H小的点加入到线段树,然后就是一个区间和. 2015-07-27:专 ...

随机推荐

  1. Java学习笔记(二十二):打包程序

    加入一个程序测试完毕,我们就可以将它打包,就可以放到服务器上运行了 找到左下角的终端 点击 输入命令: mvnw clean package -DskipTests=true clean:清除以前生成 ...

  2. python获取文件夹的大小(即取出所有文件计算大小)

    import os path = r'/Users/authurchen/PycharmProjects/Demo' # print(os.listdir(path)) ls = os.listdir ...

  3. java正则积累

    1. [.]点:再分割的时候不可以直接使用点,需要加上 \\ 转义才可以得到想要的结果,否则输出的时候会报异常 数据下标越界 String[] split = "output.txt&quo ...

  4. Mysql的时间类型问题

    时间类型有time, date, datetime, timestamp 如Mysql官方文档所述: time 没有date,date没有time,datetime是date和time的集合, 而ti ...

  5. jameter一般关注的指标

    对于B/S架构软件,一般会关注如下web服务性指标. 1.Avg Rps:平均每秒钟的响应次数==总请求次数  /  秒数 2.Avg time to last byte per terstion ( ...

  6. css3回顾 checkbox

    <div class="checkBox"> <input type="checkbox" id="check1"> ...

  7. Spring事务传递

    2018-09-25 @Transactional(propagation=Propagation.NEVER) public void update(){ Session s = sessionFa ...

  8. python 的面相对象编程--对应c++

    在python的面相对象编程中,我们常常在class中可以看到a(),  _b() ,  __c(), __d()__这样的函数. 由于我是看廖雪峰老师的教程,廖老师为了简单起见,没有引入太多概念,我 ...

  9. Python从入门到精通之First!

    Python的种类 Cpython Python的官方版本,使用C语言实现,使用最为广泛,CPython实现会将源文件(py文件)转换成字节码文件(pyc文件),然后运行在Python虚拟机上. Jy ...

  10. Oracle实现like多个值的查询

    问题背景描述: 某天客户有一个需求,给定一批的手机号码或者电话号码,查询出相关的通话记录,以及相关的一些信息. 客户给定的被叫号码如图所示:   查询出来的结果如下图所示(本批次的结果不是上图导入的结 ...