刚看到此题的时候:sb分块???
Rorshach dalao甩手一句看题
于是回去看题……果然是题读错了……

[思路]
对权值离散化后(要先读入所有输入里的权值一起离散化……所以一共有4e4个数据(~~当然你也可以不读入 hehe~~~~)) 建立一颗线段树, 线段树单点维护每一个海拔下的答案
好了问题来了, 怎么算答案呢?
我们从前到后开始扫描, 假设当前扫描到i, 离散化后的权值是now, 设它前一个离散化后的权值是pre, 那么假如(pre < now) 这一个点对答案的贡献值就是[pre + 1, now] 这个区间加一, 当然if不成立的话是不会产生贡献的
好了画样例理解一下, 我认为正确性比较显然

那么如何处理修改的操作呢?
只要先判断一下是否产生贡献, 如果有贡献就通过区间-1消去, 然后再进行重新更新即可

Code:

#include <cstdio>
#include <algorithm>
using namespace std; const int N = 4e5 + ;
const int inf = << ; int n, m, tot = , maxn =, a[N], in[N]; struct Query {
int op, pos, val;
} qn[N]; struct SegmentTree {
int s[N << ], tag[N << ]; #define lc p << 1
#define rc p << 1 | 1
#define mid (l + r) / 2 inline void up(int p) {
s[p] = s[lc] + s[rc];
} inline void down(int p, int l, int r) {
if(!tag[p]) return;
s[lc] += (mid - l + ) * tag[p];
s[rc] += (r - mid) * tag[p];
tag[lc] += tag[p], tag[rc] += tag[p];
tag[p] = ;
} void modify(int p, int l, int r, int x, int y, int v) {
if(x <= l && y >= r) {
s[p] += (r - l + ) * v;
tag[p] += v;
return;
} down(p, l, r);
if(x <= mid) modify(lc, l, mid, x, y, v);
if(y > mid) modify(rc, mid + , r, x, y, v);
up(p);
} int query(int p, int l, int r, int x) {
if(l == x && x == r) return s[p];
down(p, l, r);
int res = ;
if(x <= mid) res = query(lc, l, mid, x);
else res = query(rc, mid + , r, x);
return res;
} } seg; inline void read(int &X) {
X = ;
char ch = ;
int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void discrete() {
in[] = -inf;
sort(in + , in + + tot);
for(int i = ; i <= tot; i++) {
if(in[i] != in[i - ]) maxn++;
in[maxn] = in[i];
}
} inline int getVal(int v) {
int ln = , rn = maxn, midn;
for(; ln <= rn; ) {
midn = (ln + rn) / ;
if(in[midn] == v) return midn;
if(in[midn] < v) ln = midn + ;
else rn = midn - ;
}
return -;
} inline void init() {
int now, pre = ;
for(int i = ; i <= n; i++, pre = now) {
now = getVal(a[i]);
if(now > pre) seg.modify(, , maxn, pre + , now, );
}
} inline void solve() {
for(int i = ; i <= m; i++) {
int v = getVal(qn[i].val);
if(qn[i].op == ) {
if(qn[i].val == ) puts("");
else printf("%d\n", seg.query(, , maxn, v));
} else {
int pre = getVal(a[qn[i].pos - ]), now = getVal(a[qn[i].pos]), nxt = getVal(a[qn[i].pos + ]);
if(pre < now) seg.modify(, , maxn, pre + , now, -);
if(now < nxt) seg.modify(, , maxn, now + , nxt, -);
now = getVal(a[qn[i].pos] = qn[i].val);
if(pre < now) seg.modify(, , maxn, pre + , now, );
if(now < nxt) seg.modify(, , maxn, now + , nxt, );
}
}
} int main() {
read(n), read(m);
for(int i = ; i <= n; i++) {
read(a[i]);
in[++tot] = a[i];
}
for(int i = ; i <= m; i++) {
read(qn[i].op);
if(qn[i].op == ) {
read(qn[i].val);
in[++tot] = qn[i].val;
} else {
read(qn[i].pos), read(qn[i].val);
in[++tot] = qn[i].val;
}
} discrete();
init();
solve(); return ;
}

Luogu 3616 富金森林公园的更多相关文章

  1. 洛谷P3616 富金森林公园

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

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

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

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

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

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

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

  5. Luogu P3616 【富金森林公园】

    我们首先考虑一块石头高度变化对每个高度的查询的答案的影响, 即我们要记录,对于每个高度的查询的答案 所以要离散化高度(不然哪开的下数组啊) 不难发现,一次变化的对于不同高度的影响,对于一段连续高度是相 ...

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

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

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

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

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

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

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

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

随机推荐

  1. BZOJ5337 [TJOI2018]str

    题意 小豆参加了生物实验室.在实验室里,他主要研究蛋臼质.他现在研究的蛋臼质是由k个氨基酸按一定顺序构成的.每一个氨基酸都可能有a种碱基序 列si_j 构成.现在小豆有一个碱基串s,小豆想知道在这个碱 ...

  2. mysql5.6.11安装

    下面详细介绍5.6版本MySQL的下载.安装及配置过程. 图1.1 MySQL5.6 目前针对不同用户,MySQL提供了2个不同的版本: Ø         MySQL Community Serve ...

  3. hadoop文件IO

    InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符.它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集. Input ...

  4. webpack+vue-cli搭建项目 (vue项目重构三)

    在自己的电脑下载了npm 与 node的情况下 可使用vue-cli快速构建vue项目执行命令如下: # 全局安装 vue-cli$ npm install -g vue-cli# 创建一个基于 &q ...

  5. Tomcat设置欢迎页问题

    今天下载了tomat9,配置到eclipse后拉起来,想跑个欢迎页看看是否起好了,随手写了个index.jsp放到项目Struts2的WebContent根目录下,直接打开网页输入http://loc ...

  6. 支付宝sdk集成

    支付宝开放平台 http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1 集成步骤: 1. ...

  7. windows下通过.bat运行java程序

    在windows下运行Java项目,单独的jar可以使用,java -jar xxx.jar 运行,如果是一个zip包,里面包含了class文件和所依赖的jar的时候,可以使用 (也可以以看看这里): ...

  8. 【转】学习使用Jmeter做压力测试(三)--数据库测试

    JMeter可以做为Web服务器与浏览器之间的代理网关,以捕获浏览器的请求和Web服务器的响应,这样就可很容易的生成性能测试脚本.根据脚本,JMeter可通过线程组来模拟真实用户对Web服务器做压力测 ...

  9. Ajax 请求session过期的统一处理

    public class LoginInterceptor extends HandlerInterceptorAdapter { @SuppressWarnings("unused&quo ...

  10. python学习(十) 自带电池

    10.1 模块 >>> import math >>> math.sin(0) 0.0 10.1.1 模块是程序 假设自己写的hello.py放在c:\python ...