博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分块+二分 BZOJ 3343
阅读量:6239 次
发布时间:2019-06-22

本文共 3396 字,大约阅读时间需要 11 分钟。

3343: 教主的魔法

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1312  Solved: 585
[][][]

Description

教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是
N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、
N
每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[
L
R](1≤
L
R
N)内的英雄的身高全部加上一个整数
W。(虽然
L=
R时并不符合区间的书写规范,但我们可以认为是单独增加第
L
R)个英雄的身高)
CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [
L
R] 内有多少英雄身高大于等于
C,以验证教主的魔法是否真的有效。
WD巨懒,于是他把这个回答的任务交给了你。
 

Input

       第1行为两个整数
N
Q
Q为问题数与教主的施法数总和。
       第2行有
N个正整数,第
i个数代表第
i个英雄的身高。
       第3到第
Q+2行每行有一个操作:
(1)       若第一个字母为“M”,则紧接着有三个数字
L
R
W。表示对闭区间 [
L
R] 内所有英雄的身高加上
W
(2)       若第一个字母为“A”,则紧接着有三个数字
L
R
C。询问闭区间 [
L
R] 内有多少英雄的身高大于等于
C
 

Output

       对每个“A”询问输出一行,仅含一个整数,表示闭区间 [
L
R] 内身高大于等于
C的英雄数。
 

Sample Input

5 3
1 2 3 4 5
A 1 5 4
M 3 5 1
A 1 5 4

Sample Output

2
3

HINT

 

【输入输出样例说明】
原先5个英雄身高为1、2、3、4、5,此时[1, 5]间有2个英雄的身高大于等于4。教主施法后变为1、2、4、5、6,此时[1, 5]间有3个英雄的身高大于等于4。
 
【数据范围】
对30%的数据,
N≤1000,
Q≤1000。
对100%的数据,
N≤1000000,
Q≤3000,1≤
W≤1000,1≤
C≤1,000,000,000。

 

Source

 
[ ][ ][ ]

 

 

思路:

分块以后,对于每个询问区间[L,R],对于收尾两个区间进行暴力寻找即可。对于中间的块,我们提前进行排序然后进行二分寻找大于c-add[now_block_id]即可(因为每个块是sqrt(n)个元素,所以总的复杂度应该是n*sqrt(n)*log(n))

//看看会不会爆int!数组会不会少了一维!//取物问题一定要小心先手胜利的条件#include 
using namespace std;#pragma comment(linker,"/STACK:102400000,102400000")#define LL long long#define ALL(a) a.begin(), a.end()#define pb push_back#define mk make_pair#define fi first#define se second#define haha printf("haha\n")const int maxn = 1000000 + 5;int n, q;int block, num, belong[maxn], L[maxn], R[maxn];int add[maxn], a[maxn], d[maxn];void build_block(){ block = sqrt(n * 1.0); num = n / block; if (n % block) num++; for (int i = 1; i <= num; i++){ L[i] = (i - 1) * block + 1, R[i] = i * block; } R[num] = n; for (int i = 1; i <= n; i++) belong[i] = (i - 1) / block + 1; for (int i = 1; i <= num; i++){ sort(d + L[i], d + R[i] + 1); }}void modify(int l, int r){ for (int i = l; i <= r; i++) d[i] = a[i]; sort(d + l, d + r + 1);}void update(int ql, int qr, int w){ if (belong[ql] == belong[qr]){ for (int i = ql; i <= qr; i++) a[i] += w; modify(L[belong[ql]], R[belong[ql]]); return ; } for (int i = ql; i <= R[belong[ql]]; i++) a[i] += w; modify(L[belong[ql]], R[belong[ql]]); for (int i = L[belong[qr]]; i <= qr; i++) a[i] += w; modify(L[belong[qr]], R[belong[qr]]); for (int i = belong[ql] + 1; i < belong[qr]; i++) add[i] += w;}int query(int ql, int qr, int c){ int ans = 0; if (belong[ql] == belong[qr]){ for (int i = ql; i <= qr; i++) if (c - add[belong[ql]] <= a[i]) ans++; return ans; } for (int i = ql; i <= R[belong[ql]]; i++) if (c - add[belong[ql]] <= a[i]) ans++; for (int i = L[belong[qr]]; i <= qr; i++) if (c - add[belong[qr]] <= a[i]) ans++; for (int i = belong[ql] + 1; i < belong[qr]; i++){ int l = L[i], r = R[i]; int p = lower_bound(d + l, d + r + 1, c - add[i]) - d; ans += r + 1 - p; } return ans;}int main(){ cin >> n >> q; for (int i = 1; i <= n; i++){ scanf("%d", a + i); d[i] = a[i]; } build_block(); while (q--){ char ch[2]; int a, b, c; scanf("%s%d%d%d", ch, &a, &b, &c); if (ch[0] == 'A'){ printf("%d\n", query(a, b, c)); } else update(a, b, c); } return 0;}
View Code

 

转载于:https://www.cnblogs.com/heimao5027/p/6501540.html

你可能感兴趣的文章
Yii用ajax实现无刷新检索更新CListView数据
查看>>
JDBC的事务
查看>>
App 卸载记录
查看>>
JavaScript变量和作用域
查看>>
开源SIP服务器加密软件NethidPro升级
查看>>
Apache Pulsar中的地域复制,第1篇:概念和功能
查看>>
python pip install 出现 OSError: [Errno 1] Operation not permitted
查看>>
从源码分析scrollTo、scrollBy、Scroller方法的区别和作用
查看>>
ObjectOutputStream和ObjectInputStream
查看>>
南京大学周志华教授当选欧洲科学院外籍院士
查看>>
马士兵教学语录
查看>>
计算机网络与Internet应用
查看>>
oracle在线迁移同步数据,数据库报错
查看>>
linux性能剖析工具
查看>>
flutter中的异步
查看>>
计算机高手也不能编出俄罗斯方块——计算机达人成长之路(16)
查看>>
error LNK2001: 无法解析的外部符号 __CrtDbgReport
查看>>
# 2017-2018-1 20155224 《信息安全系统设计基础》第七周学习总结
查看>>
scikit-learn预处理实例之一:使用FunctionTransformer选择列
查看>>
邮件客户端导入邮件通讯录地址薄
查看>>