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

记当前数列长度为$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. maven 项目打包到本地仓库并且推送到私服仓库

    首先进入到项目文件夹下,然后进入cmd命令窗口,第一步先clean一下,输入命令 mvn clean. 第二步打包到本地,输入命令mvn clean package -Dmaven.test.skip ...

  2. windows、Linux同步外网NTP服务器时间

    配置 Windows 时间服务以使用外部时间源 要将内部时间服务器配置为与外部时间源同步,请使用以下方法之一: 软件自动配置  Windows 时间服务 若要自动修复此问题,请单击“下载”按钮. 在“ ...

  3. 114. Flatten Binary Tree to Linked List 把二叉树变成链表

    [抄题]: Given a binary tree, flatten it to a linked list in-place. For example, given the following tr ...

  4. 查询与删除MSSQL中所有外键约束

    查询: SELECT 主键列ID=b.rkey ,主键列名=(SELECT name FROM syscolumns WHERE colid=b.rkey AND id=b.rkeyid) ,外键表I ...

  5. node.js中实现http服务器与浏览器之间的内容缓存

    一.缓存的作用 1.减少了数据传输,节约流量. 2.减少服务器压力,提高服务器性能. 3.加快客户端加载页面的速度. 二.缓存的分类 1.强制缓存,如果缓存有效,则不需要与服务器发生交互,直接使用缓存 ...

  6. charles本地调试之map和rewrite功能

    charles是一款mac下代理调试工具,对于前端开发同学来说是相当方便的一个调试接口的工具:不过charles需要收费,不过在天朝几乎收费的软件都能找到破解方法: 使用charles前,需要将cha ...

  7. etcd-v2第四集

    coreos把etcd的image放到自家的quay.io,而不是hub.docker,或许是竞争关系,但国内下载quay.io容器极难,反正shadowsocks是下载不了. 幸好有热心爱好者搬运到 ...

  8. js常用判断和语法

    1.js获取选中的redio元素 var version = $('.version input[name="input1"]:checked').val();//单选框默认选中& ...

  9. db2实现递归调用 机构等树形数据结构形成

    WITH n(lev,ID, NAME, PORGID, ORG_ID_TREE) AS (SELECT 0,ID, NAME, PORGID, CAST(ID AS VARCHAR(1024)) F ...

  10. CPU与IRP的一些相关函数

    VOID KiAdjustIrpCredits ( VOID )其中 Number = KeNumberProcessors;Prcb = KiProcessorBlock[Index]; 多核情况下 ...