Brief description

给定一个数列,您需要支持一下两种操作:

  1. 给[l,r]同加一个数
  2. 询问[l,r]中有多少数字大于或等于v

Algorithm analyse

这个题一时想不到什么有效的数据结构,但是暴力法非常好想:一个\(\Theta(n)\)的暴力算法。

我们考虑分块做,不那么暴力。

把数据分为\(\sqrt n\)一份,那么对于每一个查询,我们都可以把这个查询分为\(\sqrt n\)个区间,修改的时候也是\(\Theta(\sqrt n)\)的级别,所以总的复杂度就是\(\Theta(\sqrt nlog\sqrt n)\)

具体地,对于每一块,我们都存储排序前和排序后的序列,这样我们就解决了这个题。

对于size的大小,我解了一个方程,跑到了2052ms,bzoj17名,已经是这个解法(不使用平衡树)的极限了,还是非常满意。

顺便%%%强校XMYZ

Code

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
int n, q, m, block;
const int maxn = 1000001;
int a[maxn], b[maxn], pos[maxn], add[maxn];
using std::sort;
using std::min;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-')
f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void reset(int x) {
int l = (x - 1) * block + 1, r = min(x * block, n);
for (int i = l; i <= r; i++)
b[i] = a[i];
sort(b + l, b + r + 1);
}
inline int find(int x, int v) {
int l = (x - 1) * block + 1, r = min(x * block, n);
int last = r;
while (l <= r) {
int mid = (l + r) >> 1;
if (b[mid] < v)
l = mid + 1;
else
r = mid - 1;
}
return last - l + 1;
}
inline void update(int x, int y, int v) {
if (pos[x] == pos[y]) {
for (int i = x; i <= y; i++)
a[i] = a[i] + v;
} else {
for (int i = x; i <= pos[x] * block; i++)
a[i] = a[i] + v;
for (int i = (pos[y] - 1) * block + 1; i <= y; i++)
a[i] = a[i] + v;
}
reset(pos[x]);
reset(pos[y]);
for (int i = pos[x] + 1; i < pos[y]; i++)
add[i] += v;
}
inline int query(int x, int y, int v) {
int sum = 0;
if (pos[x] == pos[y]) {
for (int i = x; i <= y; i++)
if (a[i] + add[pos[i]] >= v)
sum++;
} else {
for (int i = x; i <= pos[x] * block; i++)
if (a[i] + add[pos[i]] >= v)
sum++;
for (int i = (pos[y] - 1) * block + 1; i <= y; i++)
if (a[i] + add[pos[i]] >= v)
sum++;
for (int i = pos[x] + 1; i < pos[y]; i++)
sum += find(i, v - add[i]);
}
return sum;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
#endif
n = read(), q = read();
if (n >= 500000)
block = 3676;
else if (n >= 5000) {
block = 209;
} else
block = int(sqrt(n));
for (int i = 1; i <= n; i++) {
a[i] = read();
pos[i] = (i - 1) / block + 1;
b[i] = a[i];
}
if (n % block)
m = n / block + 1;
else
m = n / block;
for (int i = 1; i <= m; i++)
reset(i);
for (int i = 1; i <= q; i++) {
char ch[5];
int x, y, v;
scanf("%s", ch);
x = read(), y = read(), v = read();
if (ch[0] == 'M')
update(x, y, v);
else
printf("%d\n", query(x, y, v));
}
}

[bzoj3343]教主的魔法——分块的更多相关文章

  1. BZOJ3343: 教主的魔法 分块

    2016-05-28  10:27:19 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3343 比较显然的分块题,分块后块内排序,维护整块的附 ...

  2. BZOJ-3343教主的魔法+分块(大块排序二分)

    传送门:https://www.luogu.org/problemnew/show/P2801 参考:http://hzwer.com/2784.html  感觉思路无比清晰:) ps:我在洛谷A的, ...

  3. bzoj3343: 教主的魔法 分块 标记

    修改:两边暴力重构,中间打标记.复杂度:O(n0.5) 查询:中间二分两边暴力.O(n0.5logn0.5) 总时间复杂度O(n*n0.5logn0.5) 空间复杂度是n级别的 标记不用下传因为标记不 ...

  4. [BZOJ3343]教主的魔法

    [BZOJ3343]教主的魔法 试题描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.… ...

  5. Luogu 2801 教主的魔法 | 分块模板题

    Luogu 2801 教主的魔法 | 分块模板题 我犯的错误: 有一处l打成了1,还看不出来-- 缩小块大小De完bug后忘了把块大小改回去就提交--还以为自己一定能A了-- #include < ...

  6. BZOJ 3343: 教主的魔法(分块+二分查找)

    BZOJ 3343: 教主的魔法(分块+二分查找) 3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved:  ...

  7. 【BZOJ-3343】教主的魔法 分块

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 950  Solved: 414[Submit][Status][Discuss ...

  8. 【BZOJ3343】教主的魔法 分块+二分

    Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的 ...

  9. 【bzoj3343】教主的魔法 分块

    [bzoj3343]教主的魔法 2014年4月26日8092 Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了 ...

随机推荐

  1. 思杰VDI提示“The VDI is not available”

    前言:困扰已久的问题终于解决. 问题:客户反馈无法连接VDI. 解决过程:1.登录后台查看VDI状态为关机状态尝试重新启动提示如下图: 2.判断此VDI的启动盘出现问题(注:本人环境无数据盘) 3.查 ...

  2. android中的文件(图片)上传

    android中的文件(图片)上传其实没什么复杂的,主要是对 multipart/form-data 协议要有所了解. 关于 multipart/form-data 协议,在 RFC文档中有详细的描述 ...

  3. 在阿里云上遇见更好的Oracle(三)

    鬼扯完“去IOE”,继续回来说说这个系列文章的主角Oracle. 在DB-Engine的数据库排行榜中,Oracle已经占据了多年的第一(最新排名可以点击“阅读原文”).当然因为互联网行业的兴起,My ...

  4. 解决EasyUI DataGrid删除行失败的方法

    笔者最近在做一个项目的后台,用到了EasyUI的datagrid控件,并开启了行内编辑功能,实际上也就是使用了edatagird这个空间,引用了edatagrid.js,一切似乎都做的顺风顺水,添加数 ...

  5. Android之 GPS学习笔记

    ========================================GPS:全球定位系统 GPS由三部分组成:GPS卫星组成的空间部分,若干地面组成的控制站,用户手中的接收机.Androi ...

  6. matlab mex 小o -o 出错

    https://github.com/kyamagu/mexopencv/issues/117 就是说2014a以后的版本mex   -o 选项变成了 -output 蛋疼,这有什么好改的.找了好久才 ...

  7. Postmortem Report 第一轮迭代事后分析报告

    一.设想和目标 1.1 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件<BlueZ>是一款全新动作类塔防游戏.与市面上已经存在的塔防游戏不同 ...

  8. Java 访问权限控制 小结

    总所周知,Java提供了访问权限修饰词,以供类库开发人员向客户端程序员指明哪些是可用的,哪些是不可用的. 访问权限控制的等级,从最大权限到最小权限依次为:public.protected.包访问权限( ...

  9. poj3026(bfs+prim)最小生成树

    The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. ...

  10. 在.net2.0下使用System.Web.Script.Serialization;

    最近,在弄json字符串转为对象.需要添加这个引用System.Web.Script.Serialization;因为版本必须是dotnet2.0的原因,发现很多解决方案不适合自己.故使用这种解决办法 ...