3343: 教主的魔法

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit:
950  Solved: 414
[Submit][Status][Discuss]

Description

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

Input

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

Solution

规规矩矩的分块,不过之前从没写过

其实非常好写,看完论文后,自己YY出了正确的姿势,不过一个小BUG调了一会..

首先分成$\sqrt n$块,对于每次询问,或修改$[l,r]$

如果$l$,$r$在同一块里,就暴力修改/查询

否则,对于$l$到块结尾/快开头到$r$,两端进行暴力处理,其余的处理整个块,记录整个块的变化量

对于此题的询问,对块的处理就是每个块排序,二分出位置即可(一开始用lower_bound写WA成狗)

启发:

if后面的else是紧跟上一个if的,注意不要使之弄混(一个小细节没注意恶心了会)

二分还是自己手写比较靠谱,不要总想着找捷径

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
#define maxn 1000100
int n,q,bll,bln;
int a[maxn],aa[maxn],pos[maxn],delta[maxn];
void rebuild(int x)
{
int l=(x-)*bll+,r=min(x*bll,n);
for (int i=l; i<=r; i++) aa[i]=a[i];
sort(aa+l,aa+r+);
}
int find(int x,int c)
{
int l=(x-)*bll+,r=min(x*bll,n),last=r;
while(l<=r)
{
int mid=(l+r)>>;
if (aa[mid]<c) l=mid+;
else r=mid-;
}
return last-l+;
}
void Add(int l,int r,int ad)
{
if (pos[l]==pos[r])
for (int i=l; i<=r; i++) a[i]+=ad;
else
{
for (int i=l; i<=pos[l]*bll; i++) a[i]+=ad;
for (int i=(pos[r]-)*bll+; i<=r; i++) a[i]+=ad;
}
rebuild(pos[l]),rebuild(pos[r]);
for (int i=pos[l]+; i<=pos[r]-; i++) delta[i]+=ad;
}
int Query(int l,int r,int c)
{
int ans=;
if (pos[l]==pos[r])
for (int i=l; i<=r; i++) if (a[i]+delta[pos[i]]>=c) ans++; else continue;
else
{
for (int i=l; i<=pos[l]*bll; i++) if (a[i]+delta[pos[i]]>=c) ans++;
for (int i=(pos[r]-)*bll+; i<=r; i++) if (a[i]+delta[pos[i]]>=c) ans++;
}
// rebuild(pos[l]),rebuild(pos[r]);
for (int i=pos[l]+; i<=pos[r]-; i++) ans+=find(i,c-delta[i]);
return ans;
}
int main()
{
n=read(); q=read(); bll=int(sqrt(n)); if (n%bll) bln=n/bll+;else bln=n/bll;//bln=ceil(1.0*n/bll);
// printf("%d %d \n",bll,bln);
for (int i=; i<=n; i++) a[i]=read(),aa[i]=a[i],pos[i]=(i-)/bll+;
for (int i=; i<=bln; i++) rebuild(i);
for (int i=; i<=q; i++)
{
char opt[]; int L,R,A;
// for (int j=1; j<=n; j++) printf("%d %d %d %d %d\n",j,pos[j],a[j],aa[j],delta[j]);
scanf("%s",opt); L=read(),R=read(),A=read();
if (opt[]=='M') Add(L,R,A);
if (opt[]=='A') printf("%d\n",Query(L,R,A));
}
return ;
}

不说了,好好一个程序,被SB错误坑的改成了这样....

【BZOJ-3343】教主的魔法 分块的更多相关文章

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

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

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

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

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

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

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

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

  5. bzoj 3343 教主的魔法 分块

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

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

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

  7. BZOJ 3343教主的魔法

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

  8. bzoj 3343: 教主的魔法

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

  9. BZOJ 3343 教主的魔法(分块)

    题意: 有一个1e6的数组,t次操作:将[l,r]内的值增加w,或者查询[l,r]内的值大于等于add的 思路: 分块,块大小为sqrt(n),每次只需要暴力头尾两块,中间的整块打标记, 对于查询查操 ...

  10. [bzoj] 3343 教主的魔法 || 带修改分块

    原题 长度为n的序列,有两种操作: 1.[l,r]区间每个数+w 2.询问[l,r]区间有多少个数>c 记录lazy数组即可. #include<cstdio> #include&l ...

随机推荐

  1. notes:spm多重比较校正

    SPM做完统计后,statistical table中的FDRc实际上是在该p-uncorrected下,可以令FDR-correcred p<=0.05的最小cluster中的voxel数目: ...

  2. 工作随笔——mysql子查询删除原表数据

    最近在开发的时候遇到一个mysql的子查询删除原表数据的问题.在网上也看了很多方法,基本也是然并卵(不是写的太乱就是效率太慢). 公司DBA给了一个很好的解决方案,让人耳目一新. DELETE fb. ...

  3. WPF 让子元素动起来!

    在没有接触Blend之前,自己整出了一个MultiTouchHelper,这东西是做什么的呢?就是利用附加属性让元素可以多点触控. 然后某一天发现Blend里面有一个Behavior的东西,我去,原来 ...

  4. MVC+EF 理解和实现仓储模式和工作单元模式

    MVC+EF 理解和实现仓储模式和工作单元模式 原文:Understanding Repository and Unit of Work Pattern and Implementing Generi ...

  5. APP架子迁移指南(一)

    搭架子是脑垂体在放烟花 俗话说吃多少饭,走多少路,上学的时候捧着<设计模式>就想睡觉,现在轮子看得多了,自然有心领神会之感.搭架子就像谈哲学,如高山流水,遇弯则急.遇潭则深.我印象最深的是 ...

  6. How to create a batch of VMs with PowerShell

    Foreword When we do some test that need several VMs, we can use PowerShell script or CmdLets to impl ...

  7. [HDU5904]LCIS(DP)

    题意: 给定两个序列,求它们的最长公共递增子序列的长度, 并且这个子序列的值是连续的 n,m<=1e5,a[i],b[i]<=1e6分析:dp[i]表示以数字i结尾的序列最长长度 dp[a ...

  8. JavaScript的理解记录(1)

    1.JavaScript的数据类型分为两类:原始类型和对象类型: 原始类型包括:数字,字符串,布尔值,null和undefined; (都是不可变类型,值不可以修改) 对象类型:普通对象和函数: 函数 ...

  9. android之读取联系人信息

    联系人信息被存放在一个contacts2.db的数据库中 主要的两张表 读取联系人 读取联系人需要知道联系人内容提供者的地址,以及对应的操作对象.一般情况下操作对象是的命名方式和表明是一致的. 布局文 ...

  10. 简易版viewport

    首先这里涉及到虚拟像素和物理像素,不管是移动设备还是pc都存在这个概念1.在显示器精度还不是很高的年代,一个物理像素就等于一个虚拟像素,1000px的网页就占据了1000的物理像素(如果你玩过小霸王, ...