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. lua基础知识笔记

    一.lua中的数据类型 1.数值 a = 1 b = 1.2 2.字符串 c = "hello world" 3.布尔 d = true f = false 4.表(Table) ...

  2. npm无法安装全局web3的问题

  3. NO9——线段相关

    #include <stdio.h> #include <iostream> #include <math.h> #include <algorithm> ...

  4. MySQL初识3

    随着对MySQL的熟识,今次总结一下MySQL数据库的删除.备份和还原操作 1.数据库的删除: a.删除数据库的命令:drop database dbname; b.删除数据库中的表: 单个表:dro ...

  5. lnmp1.4,400,500,错误

    Thinkphp5或其他主流框架,入口文件未放在根目录下,比如Thinkphp5 入口文件放在/public/index.php vhost需要指向/public目录 一键安装包通常会报 open_b ...

  6. Java中的输入输出流

    FileInputStream和FileOutputStream 创建含磁盘文件的输入 输出流对象. FileInputStream继承自InputStream,用于读取本地文件中的字节数据,由于所有 ...

  7. delphi Edit 控制最大值,只能输入数字型 控制小数位数

    delphi语言受众多程序员追捧,主要原因之一就是它有很多第三方的控件可供使用.很多资深的delphi程序员都把自己积累的函数.过程等设计成控件,以方便使用,提高开发效率. 本文通过一个只允许输入数字 ...

  8. poj 2965 The Pilots Brothers' refrigerator (dfs)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17450 ...

  9. cf 442 D. Olya and Energy Drinks

    cf 442 D. Olya and Energy Drinks(bfs) 题意: 给一张\(n \times m(n <= 1000,m <= 1000)\)的地图 给出一个起点和终点, ...

  10. 洛谷 P4859 已经没有什么好害怕的了 解题报告

    已经没有什么好害怕的了 题目描述 已经使\(\tt{Modoka}\)有签订契约,和自己一起战斗的想法后,\(\tt{Mami}\)忽然感到自己不再是孤单一人了呢. 于是,之前的谨慎的战斗作风也消失了 ...