LOJ 3094 「BJOI2019」删数——角标偏移的线段树
题目:https://loj.ac/problem/3094
弱化版是 AGC017C 。
用线段树维护那个题里的序列即可。
对应关系大概是:
真实值的范围是 [ 1-m , n+m ] ;考虑设偏移量 fx ,使得 a[ i ]+fx 是真实值。如果整体 +1 ,就 fx+1 。
因为要记录每个值的个数,所以 a[ i ] 最好都是非负的。那么令 fx 的初值是 -m ,a[ i ] 的最小值是 “最小的真实值 - fx ”,就是 1-m+m 了。
已经有了 a[ ] 的范围是 [ 1 , n+2*m ] 。考虑其个数 cnt ,覆盖的范围就是 [ 1-n , n+2*m ] 。所以令 fx2=n , a[ ] 加上 fx2 对应到线段树角标即可。
注意如果是在 [ 1 , n ] 之外的值带来的覆盖,不应该考虑。因为覆盖是在值的左边,所以只需要管 >n 的值对 [ 1 , n ] 的影响。因为 n 每次最多移动 1 的位置,所以可以维护。
如果是 >n 的值因为单点修改而使得 [ 1 , n ] 的位置上的值改变,也应该忽略,只修改 “值等于该值的元素个数” 即可。
原来维护了 “区间里 0 的个数” 。这样无法应对区间减。考虑到如果需要 “区间1的个数” ,那么此时区间里一定没有 0 ,所以(看题解)想到维护区间最小值的个数即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls Ls[cr]
#define rs Rs[cr]
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
int Mn(int a,int b){return a<b?a:b;}
const int N=,N2=N*,M=N*;
int n,m,a[N],tp[N2],fx,fx2,lm;
int tot,Ls[M],Rs[M],tg[M];
struct Node{
int mn,ct;
Node(int m=,int c=):mn(m),ct(c) {}
Node operator+ (const Node &b)const
{
int tmn=Mn(mn,b.mn),tct=;
if(mn==tmn)tct+=ct; if(b.mn==tmn)tct+=b.ct;
return Node(tmn,tct);
}
}vl[M];
void build(int l,int r,int cr)
{
vl[cr].mn=; vl[cr].ct=r-l+;
if(l==r)return; int mid=l+r>>;
ls=++tot; build(l,mid,ls);
rs=++tot; build(mid+,r,rs);
}
void pshd(int cr)
{
if(!tg[cr])return; int w=tg[cr]; tg[cr]=;
tg[ls]+=w; tg[rs]+=w; vl[ls].mn+=w; vl[rs].mn+=w;
}
void mdfy(int l,int r,int cr,int L,int R,int k)
{
if(l>=L&&r<=R){ tg[cr]+=k; vl[cr].mn+=k; return;}
int mid=l+r>>; pshd(cr);
if(L<=mid)mdfy(l,mid,ls,L,R,k);
if(mid<R)mdfy(mid+,r,rs,L,R,k);
vl[cr]=vl[ls]+vl[rs];
}
Node qry(int l,int r,int cr,int L,int R)
{
if(l>=L&&r<=R)return vl[cr];
int mid=l+r>>; pshd(cr);
if(R<=mid)return qry(l,mid,ls,L,R);
if(mid<L)return qry(mid+,r,rs,L,R);
return qry(l,mid,ls,L,R)+qry(mid+,r,rs,L,R);
}
int main()
{
n=rdn();m=rdn(); fx=-m; fx2=n; lm=n+m-fx+fx2;
for(int i=;i<=n;i++)
{ a[i]=rdn()-fx; tp[a[i]]++;}
tot=; build(,lm,);
for(int i=;i<=n;i++)
{
int k=i-fx;
if(tp[k]) mdfy(,lm,,k-tp[k]++fx2,k+fx2,);
}
for(int i=,x,y;i<=m;i++)
{
x=rdn(); y=rdn();
if(x>)
{
int d=a[x]-tp[a[x]]+;
if(a[x]<=n-fx) mdfy(,lm,,d+fx2,d+fx2,-);
tp[a[x]]--;
a[x]=y-fx; tp[a[x]]++; d=a[x]-tp[a[x]]+;
if(a[x]<=n-fx) mdfy(,lm,,d+fx2,d+fx2,);
}
else
{
if(y==)
{
int k=n-fx; fx++;
if(tp[k]) mdfy(,lm,,k-tp[k]++fx2,k+fx2,-);
}
else
{
fx--; int k=n-fx;
if(tp[k]) mdfy(,lm,,k-tp[k]++fx2,k+fx2,);
}
}
Node tp=qry(,lm,,-fx+fx2,n-fx+fx2);
if(tp.mn>)tp.ct=; printf("%d\n",tp.ct);
}
return ;
}
LOJ 3094 「BJOI2019」删数——角标偏移的线段树的更多相关文章
- 【LOJ】#3094. 「BJOI2019」删数
LOJ#3094. 「BJOI2019」删数 之前做atcoder做到过这个结论结果我忘了... em,就是\([1,n]\)之间每个数\(i\),然后\([i - cnt[i] + 1,i]\)可以 ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- @loj - 2174@ 「FJOI2016」神秘数
目录 @description@ @solution@ @accepted code@ @details@ @description@ 一个可重复数字集合 S 的神秘数定义为最小的不能被 S 的子集的 ...
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏(点分树)
题意 给你一颗 \(n\) 个点的树,每个点的度数不超过 \(20\) ,有 \(q\) 次修改点权的操作. 需要动态维护带权重心,也就是找到一个点 \(v\) 使得 \(\displaystyle ...
- [BJOI2019] 删数 [dp转贪心结论+线段树]
题面 传送门 思路 dp部分 以下称合法序列为原题面中可以删空的序列 这个是我在模拟考场上的思路 一开始我是觉得,这个首先可以写成一个dp的形式:$dp[i][j]$表示用$j$个数字填满了目标序列的 ...
- 【LibreOJ】#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop 线段树+完全背包
[题目]#6396. 「THUPC2018」弗雷兹的玩具商店 / Toyshop [题意]给定一个长度为n的物品序列,每个物品有价值.不超过m的重量.要求支持以下三种操作:1.物品价值区间加减,2.物 ...
- LOJ 3090 「BJOI2019」勘破神机——斯特林数+递推式求通项+扩域
题目:https://loj.ac/problem/3090 题解:https://www.luogu.org/blog/rqy/solution-p5320 1.用斯特林数把下降幂化为普通的幂次求和 ...
- loj 3090 「BJOI2019」勘破神机 - 数学
题目传送门 传送门 题目大意 设$F_{n}$表示用$1\times 2$的骨牌填$2\times n$的网格的方案数,设$G_{n}$$表示用$1\times 2$的骨牌填$3\times n$的网 ...
随机推荐
- mysql错误:1093-You can’t specify target table for update in FROM clause的解决方法
update语句中包含的子查询的表和update的表为同一张表时,报错:1093-You can’t specify target table for update in FROM clause my ...
- spring cloud服务间调用feign
参考文章:Spring Cloud Feign设计原理 1.feign是spring cloud服务间相互调用的组件,声明式.模板化的HTTP客户端.类似的HttpURLConnection.Apac ...
- 设计模式 - 建造者模式 Builder Pattern
简介 场景 在创建复杂对象时,用户无须关心该对象所包含的属性以及它们的组装方式,只需要指定复杂对象的类型和内容就可以构建它们. 模式定义 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程 ...
- js面向对象程序设计之构造函数
再上一篇的开头说了创建对象的两种方式,一种是Object构造函数的方式,一种是对象字面量的方法.但这些方式创建多个对象的时候都会产生大量的重复代码.经过技术的进步也演化出来许多的创建对象的模式.本章会 ...
- poj1163The Triangle(动态规划,记忆化搜索)
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number triangle. Write a program that calc ...
- Proxifier全局代理
0x00前言 成功搭建使用shadowshocks实现代理访问google,然而只能浏览器代理方式使用,不能其他程序使用代理,不利于白帽子匿名安全检测,下面将介绍利用Proxifier实现全局代理 ...
- C++64位整型
今天在Ubuntu下编译C++代码,然后毫无防备的出现以下错误: 查阅了相关资料,__int64是VC++独有的,因此64位g++无法识别. 以下内容转载自:Byvoid 在C/C++中,64位整型一 ...
- ScoutSuite:一款针对云集群环境的安全审计工具
工具介绍 Scout Suite是一款针对云集群环境的开源安全审计工具,主要针对的是云端环境的安全状况.通过使用云服务提供商暴露的API,Scout Suite可以从高安全风险区域收集配置数据以备研究 ...
- SQL常用语句之数据库中表的创建、删除以及属性的修改-篇幅3
一.表的创建: CREATE TABLE [database_name.[schema_name].|schema_name.]table_name (column_name1 data_type ...
- [HDU 3625]Examining the Rooms (第一类斯特林数)
[HDU 3625]Examining the Rooms (第一类斯特林数) 题面 有n个房间,每个房间有一个钥匙,钥匙等概率的出现在n个房间内,每个房间中只会出现且仅出现一个钥匙.你能炸开门k次, ...