「 Luogu P2801 」 教主的魔法——分块
# 解题思路
修改,就是一个区间修改的常规操作,但是为了迎合查询的需要,对两端的不完整的块需要暴力重构,重新进行排序操作,保证每一块都是单调上升的顺序。
然后再说进行查询的操作,起初,我们需要在每一个块内进行排序。保证顺序时单调上升的(在每一个块内,是独立的),然后查询的时候对每一块($k$)都二分查找到大于 $num + tag[k]$ 的第一个数的位置,然后就可以得到一共有多少大于 $num$ 的数了。
值得注意的是,有些题解写的是对原序列直接进行排序,这就有一个错误,那就是在排序之后序列的顺序改变,改变了之后在进行区间修改的时候就不能保证正确性了。
所以我们开一个 vector 将每个块内的数都存下来。我的代码 T 了一个点,但是了 O2 过了,懒得再去卡常了
# 附上代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 1e6+;
int N, Q, arr[maxn], in[maxn], cnt, tag[maxn];
vector<int> b[];
struct BLOCK {
template <typename T> inline void read(T &x) {
x = ; T f = ; char c = getchar();
while (c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while (c <= '' && c >= '') {x = x* + c-''; c = getchar();}
x *= f;
}
void reset(int k) {
b[k].clear();
for(int i=(k-)*cnt+; i<=min(k*cnt, N); i++)
arr[i] += tag[k], b[k].push_back(arr[i]);
sort(b[k].begin(), b[k].end());
tag[k] = ;
}
void build() {
cnt = sqrt(N);
for(int i=; i<=N; i++) {
read(arr[i]);
in[i] = (i-)/cnt+;
b[in[i]].push_back(arr[i]);
}
for(int i=in[]; i<=in[N]; i++)
sort(b[i].begin(), b[i].end());
}
void update(int l, int r, int num) {
for(int i=l; i<=min(in[l]*cnt, r); i++)
arr[i] += num;
reset(in[l]);
if(in[l] != in[r]) {
for(int i=(in[r]-)*cnt+; i<=r; i++)
arr[i] += num;
reset(in[r]);
}
for(int i=in[l]+; i<in[r]; i++)
tag[i] += num;
}
int check(int k, int num) {
int ans = (b[k].end()-lower_bound(b[k].begin(), b[k].end(), num-tag[k]));
return ans;
}
int query(int l, int r, int num) {
int ans = ;
for(int i=l; i<=min(in[l]*cnt, r); i++)
if(arr[i] + tag[in[i]] >= num) ans ++;
if(in[l] != in[r]) {
for(int i=(in[r]-)*cnt+; i<=r; i++)
if(arr[i] + tag[in[i]] >= num) ans ++;
}
for(int i=in[l]+; i<in[r]; i++)
ans += check(i, num);
return ans;
}
BLOCK () {
read(N), read(Q);
build();
char opt;
int l, r, num;
for(int i=; i<=Q; i++) {
cin>>opt;
read(l), read(r), read(num);
if(opt == 'M') update(l, r, num);
else printf("%d\n", query(l, r, num));
}
}
}BLO;
int main() {}
「 Luogu P2801 」 教主的魔法——分块的更多相关文章
- 「BZOJ3343」教主的魔法(分块+二分查找)
题意: 给定一个数列,您需要支持以下两种操作:给[l,r]同加一个数询问[l,r]中有多少数字大于或等于v (n<=1000000,m<=3000) 题解 块内排序二分查询修改就用个数组存 ...
- Luogu 2801 教主的魔法 | 分块模板题
Luogu 2801 教主的魔法 | 分块模板题 我犯的错误: 有一处l打成了1,还看不出来-- 缩小块大小De完bug后忘了把块大小改回去就提交--还以为自己一定能A了-- #include < ...
- BZOJ 3343: 教主的魔法(分块+二分查找)
BZOJ 3343: 教主的魔法(分块+二分查找) 3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1172 Solved: ...
- 洛谷P2801 教主的魔法 [分块,二分答案]
题目传送门 教主的魔法 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. ...
- 题解 P2801 【教主的魔法】
分块入门题,不错的,建议大家做一做 开始学习 先看一下数列分块入门 2 这道题想让我们求区间[l,r]>=c的个数,然后我们可以看到"数列分块入门 2"是求区间[l,r]&l ...
- BZOJ 3343: 教主的魔法 [分块]【学习笔记】
3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1172 Solved: 526[Submit][Status][Discus ...
- 【BZOJ-3343】教主的魔法 分块
3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 950 Solved: 414[Submit][Status][Discuss ...
- 【BZOJ3343】教主的魔法 分块+二分
Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的 ...
- BZOJ3343: 教主的魔法 分块
2016-05-28 10:27:19 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3343 比较显然的分块题,分块后块内排序,维护整块的附 ...
随机推荐
- sublime text3 注册码
—– BEGIN LICENSE —– TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60790 61AA ...
- 严格次小生成树(lca + 倍增)
题目描述 小C最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当小C洋洋得意之时,小P又来泼小C冷水了.小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得 ...
- cmd - 批量重命名文件
相信大家或多或少都遇到过类似的情况:从网上下载了好多图片(或者其他的文件),这些图片的名字往往都是些乱七八糟的字母数字的组合,我们想要一次性修改几十张上百张的图片的名字应该怎么办呢? 这里有两种方法, ...
- Chemistry in Berland CodeForces - 846E
题目 题意: 有n种化学物质,第i种物质现有bi千克,需要ai千克.有n-1种,编号为2-n的转换方式,每种都为(x,k),第i行是编号为i+1的转换方式,编号为i的转换方式(xi,ki)表示ki千克 ...
- magento 自定义url路径 和 filter data 小结
背景是往一个第三方的搜索插件里面加入filter功能. 首先是路径,插件自己定义了一个router,类似于cms.那首先说说router好了,从入口一路追查的话,会发现最后进入的是Mage_Core_ ...
- HTML form label
在表单布局中会遇到label标签的使用,label没有任何样式效果,有触发对应表单控件功能.比如我们点击单选按钮或多选框前文字对应选项就能被选中,这个就是对文字加了<label>标签实现. ...
- P2955 [USACO09OCT]奇数偶数Even? Odd?
题目描述 Bessie's cruel second grade teacher has assigned a list of N (1 <= N <= 100) positive int ...
- mysql索引原理及创建与查询
索引介绍 一:为什么要有索引 索引是用来优化查询效率(速度)的 没有索引的话,对于大数据的表,就只能每次都遍历一遍,数据量越大,耗时越多有索引的话,可以提升好几个数量级的速度 一般的应用系统,读写比例 ...
- 初学web前端,掌握这些就足够了!
Web开发如今是如日中天,热的发烫.那我们应该怎么学习呢?这不光是初学者,很多学了几年的人也会有些迷茫或者彷徨,大家也都知道不断学习是不可避免的,不学习肯定要掉队:那怎么学效率更高,那些是坑,那些是路 ...
- Math.net,.net上的科学计算利器
F#在科学计算领域的应用,包括部分语法介绍. Math.net,.net上的科学计算利器 摘要: .net上科学计算个人觉得首选numpy和scipy for dotnet.因为这两个库用户数量已经非 ...