【BZOJ-3343】教主的魔法 分块
3343: 教主的魔法
Time Limit: 10 Sec Memory Limit: 256 MB
Submit:
950 Solved: 414
[Submit][Status][Discuss]
Description
R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)
内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。
Input
第1行为两个整数N、Q。Q为问题数与教主的施法数总和。
第2行有N个正整数,第i个数代表第i个英雄的身高。
若第一个字母为“M”,则紧接着有三个数字L、R、W。表示对闭区间 [L,
R] 内所有英雄的身高加上W。
若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R]
内有多少英雄的身高大于等于C。
Output
R] 内身高大于等于C的英雄数。
Sample Input
1 2 3 4 5
A 1 5 4
M 3 5
1
A 1 5 4
Sample Output
3
HINT
5]间有2个英雄的身高大于等于4。教主施法后变为1、2、4、5、6,此时[1, 5]间有3个英雄的身高大于等于4。
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】教主的魔法 分块的更多相关文章
- BZOJ 3343: 教主的魔法(分块+二分查找)
BZOJ 3343: 教主的魔法(分块+二分查找) 3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1172 Solved: ...
- BZOJ 3343: 教主的魔法 [分块]【学习笔记】
3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1172 Solved: 526[Submit][Status][Discus ...
- Bzoj 3343: 教主的魔法(分块+二分答案)
3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MB Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息 ...
- Bzoj 3343: 教主的魔法 分块,二分
3343: 教主的魔法 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 821 Solved: 364[Submit][Status][Discuss ...
- bzoj 3343 教主的魔法 分块
修改直接对整块打标记,两边暴力. 查询需要保证每个整块有序,所以在修改时排序就好啦 #include<cstdio> #include<cstring> #include< ...
- BZOJ——3343: 教主的魔法 || 洛谷—— P2801 教主的魔法
http://www.lydsy.com/JudgeOnline/problem.php?id=3343 || https://www.luogu.org/problem/show?pid=280 ...
- BZOJ 3343教主的魔法
Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的 ...
- bzoj 3343: 教主的魔法
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 924 Solved: 402[Submit][Status][Discuss] Descriptio ...
- BZOJ 3343 教主的魔法(分块)
题意: 有一个1e6的数组,t次操作:将[l,r]内的值增加w,或者查询[l,r]内的值大于等于add的 思路: 分块,块大小为sqrt(n),每次只需要暴力头尾两块,中间的整块打标记, 对于查询查操 ...
- [bzoj] 3343 教主的魔法 || 带修改分块
原题 长度为n的序列,有两种操作: 1.[l,r]区间每个数+w 2.询问[l,r]区间有多少个数>c 记录lazy数组即可. #include<cstdio> #include&l ...
随机推荐
- 夯实基础之php学习-1基础篇
1,单引号和双引号的区别 单引号表示字符串,双引号能解析字符串中的变量,所以,如果没有变量,尽量用单引号,加快解析速度 当字符串需要单引号或者双引号的时候,可以用转义字符代替 2,类型转换 通过(bo ...
- SQL80001: Incorrect syntax near ':'
原文连接:http://geekswithblogs.net/tonyt/archive/2010/03/05/138363.aspx SQL80001: Incorrect syntax nea ...
- Shell脚本语法
索引 1. 第一行必须是"#!/bin/sh" 2. 注释:一行开头为 # 3. 定义变量 4. 逻辑符号 5. 接收参数 6. 控制流:if/then/elif/else/f ...
- Android 常用的adb命令
1.安装APK(如果加 -r 参数,保留已设定数据,重新安装filename.apk) adb install xxx.apk adb install -r xxx.apk 2.卸载APK(如果加 - ...
- QT 数据库编程二
//logindlg.cpp #include "logindlg.h" #include <QGridLayout> #include <QHBoxLayout ...
- QT 常用控件二
QT提供QHBoxLayout类.QVBoxlayout类及QGridLayout类等的基本布局管理,分别是水平排列布局,垂直排列布局和网格排列布局 addWidget()方法用于向布局中加入需要布局 ...
- DOM Element节点类型详解
上文中我们讲解了 DOM 中最重要的节点类型之一的 Document 节点类型,本文我们继续深入,谈谈另一个重要的节点类型 Element . 1.概况 Element 类型用于表现 HTML 或 X ...
- checkboxlist 下拉框多选功能 ,模拟dropdownlist带复选框效果
前台代码 01.<html xmlns="http://www.w3.org/1999/xhtml"> 02.<head runat="server&q ...
- 狗屎的Java规范
规范 标题真有点侮辱了狗. 最近做Java,C#与Java对比笔记: http://www.cnblogs.com/newsea/p/4839540.html 其实Java语法弱点就弱点,关键是Jav ...
- Overlay network 覆盖网络
From Wikipedia, the free encyclopedia An overlay network is a computer network that is built on top ...