我们首先考虑一块石头高度变化对每个高度的查询的答案的影响,

我们要记录,对于每个高度的查询的答案

所以要离散化高度(不然哪开的下数组啊)

不难发现,一次变化的对于不同高度的影响,对于一段连续高度是相同的

即一次修改操作,对于一段连续高度的答案,影响相同,满足区间修改性质

就决定是你了,树状数组

具体来说,考虑修改位置修改前后和两边的高度关系

但是情况很多,不妨把修改操作换成先删除(把高度降为0),再插入

考虑删除,插入的话,反过来就好,中间的是删除位置

情况1:中间比两边低

最简单的情况,不难发现,删除掉中间的只能让高度为$part1$的区间的答案$+1$,因为它割裂了两边的连续区间

情况2:中间比两边高

最高的区间影响就很广了

对于$part1:$它的删除会割裂两边的区间$val~of~part1++$

对于$part2:$因为两边没有构成连续区间,所以没有影响

对于$part3:$原来是有露出来的,现在没了,当然要减掉了

情况3:中间的高度也中等

也很简单了,只对$part1$有影响

然而这样处理的只是答案的变化,我们还需要统计初始答案

还是考虑高度变化对答案的影响,不难发现,随着高度上升,未被覆盖的点的个数是单调不升的

按高度开$vector$,把每个高度恰好被覆盖的所有位置扔进去

从小到大枚举高度,先将这个高度的答案设为上一个高度的答案,取出这个高度恰好被覆盖的所有位置,统计这个位置的影响

如果它比两边高,类比上面情况2,答案减一

低呢,答案加一

这样我们就解决了这个问题

上代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=2e5+;
vector<int>v[*maxn];
int pre[*maxn],n,m,a[maxn],mp[*maxn],op[maxn],cnt,b[maxn],d[maxn],c[*maxn];
bool vis[*maxn];
int lowbit(int x)
{
return x&-x;
}
int sum(int x)
{
int ret=;
while(x)
{
ret+=c[x];
x-=lowbit(x);
}
return ret;
}
void add(int x,int ch)
{
while(x<=cnt)
{
c[x]+=ch;
x+=lowbit(x);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
mp[++cnt]=a[i];
}
for(int i=;i<=m;i++)
{
scanf("%d",&op[i]);
if(op[i]==)
scanf("%d",&b[i]),mp[++cnt]=b[i];
else
scanf("%d%d",&d[i],&b[i]),mp[++cnt]=b[i];
}
sort(mp+,mp+cnt+);
cnt=unique(mp+,mp+cnt+)-mp-;
for(int i=;i<=n;i++)
{
a[i]=lower_bound(mp+,mp+cnt+,a[i])-mp;
v[a[i]+].push_back(i);
}
for(int i=;i<=m;i++)
b[i]=lower_bound(mp+,mp+cnt+,b[i])-mp;
pre[]=,vis[]=vis[n+]=;
for(int i=;i<=cnt;i++)
{
pre[i]=pre[i-];
for(int j=;j<v[i].size();j++)
{
int u=v[i][j];
vis[u]=;
if(!vis[u-]&&!vis[u+])
pre[i]++;
else if(vis[u-]&&vis[u+])
pre[i]--;
}
}
for(int i=;i<=m;i++)
{
if(op[i]==)
printf("%d\n",pre[b[i]]+sum(b[i]));
else
{
int tmp[];
tmp[]=a[d[i]-],tmp[]=a[d[i]],tmp[]=a[d[i]+];
sort(tmp+,tmp+);
if(a[d[i]]>=a[d[i]-]&&a[d[i]]>=a[d[i]+])
add(tmp[]+,-),add(tmp[]+,);
add(,),add(tmp[]+,-);
tmp[]=a[d[i]-],tmp[]=b[i],tmp[]=a[d[i]+];
sort(tmp+,tmp+);
if(b[i]>=a[d[i]-]&&b[i]>=a[d[i]+])
add(tmp[]+,),add(tmp[]+,-);
add(,-),add(tmp[]+,);
a[d[i]]=b[i];
}
}
return ;
}

Luogu P3616 【富金森林公园】的更多相关文章

  1. 洛谷 P3616 富金森林公园题解(树状数组)

    P3616 富金森林公园 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积水也有 ...

  2. 树状数组 洛谷P3616 富金森林公园

    P3616 富金森林公园 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积水也有 ...

  3. 洛谷P3616 富金森林公园

    题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积水也有一个海拔高度,所有严格低于 ...

  4. ●洛谷 P3616 富金森林公园

    题链: https://www.luogu.org/problemnew/show/3616 题解: 树状数组,,, 本题思路挺巧妙. 考虑这种暴力算法:(设H[i]为i位置的高度,水面的高度为B) ...

  5. 洛谷 P3616 富金森林公园 [树状数组]

    传送门 维护一个山脉,单点修改,查询有多少山峰高出水面 我是沙茶沙茶题都不会做只想到无修改可以用扫描线 答案就是所有比水面高的-相邻都比水面高的啊 因为没有区间询问写个$BIT$都可以 有区间询问?可 ...

  6. Luogu 3616 富金森林公园

    刚看到此题的时候:sb分块??? Rorshach dalao甩手一句看题 于是回去看题……果然是题读错了…… [思路] 对权值离散化后(要先读入所有输入里的权值一起离散化……所以一共有4e4个数据( ...

  7. 【树状数组 思维题】luoguP3616 富金森林公园

    树状数组.差分.前缀和.离散化 题目描述 博艾的富金森林公园里有一个长长的富金山脉,山脉是由一块块巨石并列构成的,编号从1到N.每一个巨石有一个海拔高度.而这个山脉又在一个盆地中,盆地里可能会积水,积 ...

  8. 洛谷 P1477 [NOI2008]假面舞会

    题目链接 题目描述 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会. 今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一 个自己喜欢的面具.每个面具都有一个编号,主办方 ...

  9. Java Web开发和Python Web开发之间的区别

    今天的文章讨论了Java Web开发和Python Web开发之间的区别.我不鼓励我们在这里从Java Web迁移到Python Web开发.我只是想谈谈我的感受.它不一定适合所有情况,仅供我们参考. ...

随机推荐

  1. 函数和常用模块【day04】:内置函数(十)

    一.36-40 36.isinstance(object, classinfo) 功能:用于判断,对象是否是某个类的实例 # s = "alex" # 对象,"alex& ...

  2. redis工具类 ----RedisPoolUtil

    这里介绍一下,这个工具类不是在分布式环境下来用的,就是我们平常使用的,单机状况下,为什么博主开头要这样强调呢?因为,之前见网上有些博友有这样封装的,也有RedisShardedPoolUtil 封装的 ...

  3. vscode 配置Git

    步骤: 下载Git客户端 配置环境变量 设置vscode与Git的关联 重启 步骤一: 该网址,下载即可. https://git-scm.com/downloads 步骤二: 计算机 > 属性 ...

  4. C++11模板友元语法

    第 1 类: 普通类A的 普通类B 友元(一对一友好关系): 无需前置声明class B,当class B第一次出现在friend声明中时,该名字被隐式地认为可见. class A { friend ...

  5. 前端 - js方式Ajax/ jquery方式Ajax / 伪 ajax /伪ajax 进阶方式

    DJANGO环境搭建: 目录文件: 关闭CSRF 添加目录文件路径 配置url 视图配置: index页面配置: 测试:(成功) 进入正题: ajax 通过GET提交数据至后台: <!DOCTY ...

  6. Maven继承

    继承为了消除重复,可以把pom 中很多相同的配置提取出来:如:grouptId, version 等. 在使用的时候子工程直接继承父工程的依赖版本号,子工程中不再需要指定具体版本号,方便统一管控项目的 ...

  7. Android:(本地、可通信的、前台、远程)Service使用全面介绍

    2.具体使用解析 2.1 本地Service 这是最普通.最常用的后台服务Service. 2.1.1 使用步骤 步骤1:新建子类继承Service类 需重写父类的onCreate().onStart ...

  8. POI导出带格式的Excel模板——(六)

    Jar包

  9. yum和rpm的区别

    rpm是由红帽公司开发的软件包管理方式,使用rpm我们可以方便的进行软件的安装.查询.卸载.升级等工作.但是rpm软件包之间的依赖性问题往往会很繁琐,尤其是软件由多个rpm包组成时.Yum(全称为 Y ...

  10. 使用 Linux 系统调用的内核命令【转】

    转自:http://www.ibm.com/developerworks/cn/linux/l-system-calls/ 探究 SCI 并添加自己的调用 Linux® 系统调用 —— 我们每天都在使 ...