Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 924  Solved: 402
[Submit][Status][Discuss]

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。
 
题解:
  想用线段树什么的维护可是每次询问的C都不定,不好处理,只好分块来做了。
  把1~N个数字每sqrt(N)分成一块,末尾可能有剩余的不足sqrt(N)的单独分成一块。a[]表示初始序列,b[]则储存a[]的块内排序后的结果,add[]是块内累加标记。
  对于M操作,l和r若在同一区间,说明范围很小,直接暴力修改a[],然后重构b[],如果l和r不在同一区间,则区间内的整块部分直接打标记,两端可能有不是整块的部分暴力修改a[],然后重构b[]。
  对于A操作,l和r若在同一区间,直接暴力判断,如果不在,两端部分暴力,中间部分由于b[]是有序的,可以用二分来解决。
 #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long LL;
const int maxn=;
int N,Q,M,block;
int a[maxn],b[maxn],pos[maxn],add[maxn];
char s[];
inline void reset(int x){
int l=(x-)*block+,r=min(N,x*block);
for(int i=l;i<=r;i++) b[i]=a[i];
sort(b+l,b+r+);
}
inline void update(int l,int r,int delta){
if(pos[l]==pos[r]){
for(int i=l;i<=r;i++) a[i]+=delta;
}
else{
for(int i=l;i<=pos[l]*block;i++) a[i]+=delta;
for(int i=(pos[r]-)*block+;i<=r;i++) a[i]+=delta;
}
reset(pos[l]); reset(pos[r]);
for(int i=pos[l]+;i<=pos[r]-;i++) add[i]+=delta;
}
inline int find(int l,int r,int v){
if(l+>=r){
if(b[l]>=v) return l;
else return r;
}
int mid=(l+r)>>;
if(b[mid]>=v) return find(l,mid,v);
else return find(mid+,r,v);
}
inline int query(int l,int r,int z){
int sum=;
if(pos[l]==pos[r]){
for(int i=l;i<=r;i++)
if(a[i]+add[pos[i]]>=z) sum++;
}
else{
for(int i=l;i<=pos[l]*block;i++)
if(a[i]+add[pos[i]]>=z) sum++;
for(int i=(pos[r]-)*block+;i<=r;i++)
if(a[i]+add[pos[i]]>=z) sum++;
}
for(int i=pos[l]+;i<=pos[r]-;i++){
sum+=(i*block+)-find((i-)*block+,i*block+,z-add[i]);
}
return sum;
}
int main(){
scanf("%d%d",&N,&Q);
block=int(sqrt(N));
for(int i=;i<=N;i++){
scanf("%d",&a[i]); b[i]=a[i];
pos[i]=(i-)/block+;
}
if(N%block!=) M=N/block+;
else M=N/block;
for(int i=;i<=M;i++) reset(i);
while(Q--){
int x,y,z;
scanf("%s%d%d%d",s,&x,&y,&z);
if(s[]=='M') update(x,y,z);
else printf("%d\n",query(x,y,z));
}
return ;
}

最新文章

  1. LeetCode - 72. Edit Distance
  2. tshark过滤并保存包特定字段
  3. Delphi Memory-Mapped File简单示例
  4. Android UI 之 Tab类型界面总结
  5. WPF 界面控件遍历和后台行为绑定写法
  6. NGINX(七)分段下载
  7. Canvas前端游戏开发——FlappyBird详解
  8. 在Centos 5.6下安装 redis
  9. Linux常用命令及使用技巧
  10. NFC学习笔记2——Libnfc简介及安装
  11. lnmp pathinfo问题
  12. Asp.Net Core写个共享磁盘文件Web查看器
  13. 如何解决Linux 系统下 ifconfig 命令无网络接口 ens33
  14. Maven 下添加oracle11g的包 报Missing artifact com.oracle:ojdbc6:jar:11.2.0.1.0
  15. 2:if 语句
  16. (转)Python Mixins 机制
  17. CF10D LCIS
  18. 解决Redis/Codis Connection with master lost(复制超时)问题
  19. cocos进阶教程(3)Lua加密技术
  20. 使用Bus.js进行兄弟(非父子)组件通信

热门文章

  1. kafka配置文件注解
  2. Django - 学习目录
  3. oracle数据迁移到mysql
  4. CH0103 最短Hamilton路径 dp
  5. mysql 内置功能 存储过程 目录
  6. python float()
  7. webdriver鼠标上下滑动
  8. asp.net本地读取excel正确。但在iis服务器上就报错 未在本地计算机上注册“Microsoft.ACE.OleDb.12.0”提供程序
  9. sql中 substring和charindex 的用法
  10. OAuth 白话简明教程 3.客户端模式(Client Credentials)