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

3343: 教主的魔法

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1172  Solved: 526
[Submit][Status][Discuss]

这个题目为什么不能用线段树做事因为C的值不固定,如果用线段树来做,那么每一个C值要从新建一遍线段树,时间会爆炸的

add操作:
1.同一块暴力修改,然后重构
2.两端不完整的暴力修改重构,中间完整的块加标记
查询操作:
1.同一块暴力
2.两端暴力,中间在b中二分查找

Description

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

Input

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

Output

       对每个“A”询问输出一行,仅含一个整数,表示闭区间 [LR] 内身高大于等于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。

简单想了一下,主席树不好做,莫队也不好做(询问之间不好转移)
那就暴力分块了
 
bl是块的大小,m是块的个数,pos[i]为i所在块的编号
b数组维护每个块排好序的
add操作:
1.同一块暴力修改,然后重构
2.两端不完整的暴力修改重构,中间完整的块加标记
查询操作:
1.同一块暴力
2.两端暴力,中间在b中二分查找
 
问题:
1.注意二分查找写法,找大于等于
2.l=(x-1)*bl+1,r=min(x*bl,n)
3.不要漏加/多加pos
 
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e6+5,M=1e3+5;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n,Q,bl,m,a[N],pos[N],b[N],add[M],x,y,z;
char s[10];
void reset(int x){
int l=(x-1)*bl+1,r=min(x*bl,n);
for(int i=l;i<=r;i++) b[i]=a[i];
sort(b+l,b+r+1);
}
void change(int l,int r,int v){
if(pos[l]==pos[r]){
for(int i=l;i<=r;i++) a[i]+=v;
reset(pos[l]);
}else{
int t=pos[l]*bl;
for(int i=l;i<=t;i++) a[i]+=v;
for(int i=(pos[r]-1)*bl+1;i<=r;i++) a[i]+=v;
reset(pos[l]);reset(pos[r]);
for(int i=pos[l]+1;i<pos[r];i++) add[i]+=v;
}
}
inline int find(int x,int v){
int l=(x-1)*bl+1,r=min(x*bl,n),t=r;
while(l<=r){
int mid=(l+r)>>1;
if(b[mid]<v) l=mid+1;
else r=mid-1;
}
return t-l+1;
}
int query(int l,int r,int v){
int ans=0;
if(pos[l]==pos[r]){
for(int i=l;i<=r;i++) if(a[i]+add[pos[i]]>=v) ans++;
return ans;
}else{
int t=pos[l]*bl;
for(int i=l;i<=t;i++) if(a[i]+add[pos[i]]>=v) ans++;
for(int i=(pos[r]-1)*bl+1;i<=r;i++) if(a[i]+add[pos[i]]>=v) ans++;
for(int i=pos[l]+1;i<pos[r];i++) ans+=find(i,v-add[i]);
return ans;
}
}
int main(){
n=read();Q=read();
bl=sqrt(n);
m=n/bl;if(n%bl) m++;
for(int i=1;i<=n;i++) a[i]=read(),pos[i]=(i-1)/bl+1;
for(int i=1;i<=m;i++) reset(i);
while(Q--){
scanf("%s",s);x=read();y=read();z=read();
if(s[0]=='M') change(x,y,z);
else printf("%d\n",query(x,y,z));
}
}
 

BZOJ 3343: 教主的魔法(分块+二分查找)的更多相关文章

  1. Bzoj 3343: 教主的魔法(分块+二分答案)

    3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MB Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息 ...

  2. Bzoj 3343: 教主的魔法 分块,二分

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

  3. BZOJ 3343: 教主的魔法 [分块]【学习笔记】

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved: 526[Submit][Status][Discus ...

  4. 「BZOJ3343」教主的魔法(分块+二分查找)

    题意: 给定一个数列,您需要支持以下两种操作:给[l,r]同加一个数询问[l,r]中有多少数字大于或等于v (n<=1000000,m<=3000) 题解 块内排序二分查询修改就用个数组存 ...

  5. bzoj 3343 教主的魔法 分块

    修改直接对整块打标记,两边暴力. 查询需要保证每个整块有序,所以在修改时排序就好啦 #include<cstdio> #include<cstring> #include< ...

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

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

  7. bzoj 3343: 教主的魔法

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 924  Solved: 402[Submit][Status][Discuss] Descriptio ...

  8. BZOJ——3343: 教主的魔法 || 洛谷—— P2801 教主的魔法

    http://www.lydsy.com/JudgeOnline/problem.php?id=3343  ||  https://www.luogu.org/problem/show?pid=280 ...

  9. BZOJ 3343教主的魔法

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

随机推荐

  1. Java基础(二)--this关键字及初始化

    构造器: 构造器的名称必须和类名完全相同,所以一般方法的"首字母小写"命名规则并不适合构造器 默认构造器: 也叫无参构造器,作用就是创建一个默认对象,如果你不是手写出来,编译器默认 ...

  2. 13EL表达式语言

    EL表达式语言 EL表达式语言 JSP用于在页面上显示动态内容,通常需要在JSP页面中嵌入Java脚本以完成复杂功能.但大量的Java脚本使得JSP页面难以维护.一种类似JavaScript语言—EL ...

  3. 出生年 (15 分) C解法

    出生年 以上是新浪微博中一奇葩贴:"我出生于1988年,直到25岁才遇到4个数字都不相同的年份."也就是说,直到2013年才达到"4个数字都不相同"的要求.本题 ...

  4. 数据类型对应字节数(32位,64位 int 占字节数)

    数据类型对应字节数(32位,64位 int 占字节数) 可用如sizeof(char),sizeof(char*)等得出 32位编译器: char :1个字节 char*(即指针变量): 4个字节(3 ...

  5. 【IDEA】【Git】pull代码始终无法pull到最新的代码或者提示pull no items 【解决方式】

    最近pull代码老是提示pull no items,但是本地并不是最新的代码,看了各种博客始终无法解决,最后靠自己的方式解决.下面是解决方法. 方法:1.首先git --> repository ...

  6. C++关键字:explicit

    #include "pch.h" #include <iostream> using namespace std; class BaseClass { public: ...

  7. jmeter录制火狐浏览器

    昨天看youtube,居然发现有这功能,啊哈哈 听不懂英语 也能有收获. 一.Jmeter 文件中选择Templates->Recording 二.创建之后,自动出现一个模板: 1. Threa ...

  8. (五)python3 整型int

    int() Python 内置函数,用于将一个字符串或数字转换为整型. int(x, base=10)#以十进制转换x为整型(默认) >>>int() # 不传入参数时,得到结果0 ...

  9. PAT 1137 Final Grading

    For a student taking the online course "Data Structures" on China University MOOC (http:// ...

  10. java方法的虚分派和方法表

    java:方法的虚分派(virtual dispatch)和方法表(method table) Java方法调用的虚分派 虚分配(Virtual Dispatch) 首先从字节码中对方法的调用说起.J ...