[luoguP2801] 教主的魔法(二分 + 分块)
以为对于这类问题线段树都能解决,分块比线段树菜,结果培训完才知道线段树是一种特殊的分块方法,有的分块的题线段树不能做,看来分块还是有必要学的。
对于这个题,先分块,然后另开一个数组对于每个块内排序。
区间加的话,加一个标记,每一个整块区间加,里面的数的相对大小不变,而左右两边零散的块直接暴力重构。
查询可以对于每个块二分查找。
时间复杂度应该是 nlogn + Q√nlog√n,刚好卡过。。
注意:第10个点会被卡,手写二分比stl的lower_bound快一点,可以避免被卡。
也可以在 S = sqrt(n) 后面 + x,x 不要太大也不要太小,不知道为什么,速度也会快点,玄学啊。
%%%有些dalao不知道怎么写的,1000ms
——代码(最终只能优化到1600ms)
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
#define LL long long const int MAXN = ;
int n, q, S, C;
int belong[MAXN], st[MAXN], ed[MAXN];
LL a[MAXN], b[MAXN], add[MAXN]; inline LL read()
{
LL x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = x * + ch - '';
return x * f;
} inline int find(int x, int y, int z)
{
int mid;
while(x < y)
{
mid = (x + y) >> ;
if(b[mid] >= z) y = mid;
else x = mid + ;
}
return x;
} inline void retreat(int x, int y)
{
int i;
for(i = x; i <= y; i++) b[i] = a[i];
std::sort(b + x, b + y + );
} inline void init()
{
int i, j;
S = int(sqrt(n)) + ;
for(i = ; i <= n; i++) scanf("%d", &a[i]);
for(i = ; i <= n; i += S)
{
st[++C] = i;
ed[C] = std::min(i + S - , n);
}
for(i = ; i <= C; i++)
for(j = st[i]; j <= ed[i]; j++)
belong[j] = i;
for(i = ; i <= C; i++) retreat(st[i], ed[i]);
} inline void update(int x, int y, LL z)
{
int i, l = belong[x], r = belong[y];
if(l == r)
{
for(i = x; i <= y; i++) a[i] += z;
retreat(st[l], ed[r]);
}
else
{
for(i = x; i <= ed[l]; i++) a[i] += z;
for(i = l + ; i <= r - ; i++) add[i] += z;
for(i = st[r]; i <= y; i++) a[i] += z;
retreat(st[l], ed[l]);
retreat(st[r], ed[r]);
}
} inline int query(int x, int y, LL z)
{
int i, l = belong[x], r = belong[y], ans = ;
if(l == r) return y + - find(x, y + , z - add[l]);
ans += ed[l] - find(x, ed[l] + , z - add[l]) + ;
for(i = l + ; i <= r - ; i++) ans += ed[i] - find(st[i], ed[i] + , z - add[i]) + ;
ans += y - find(st[r], y + , z - add[r]) + ;
return ans;
} int main()
{
int i, j, x, y;
LL z;
char ch;
n = read();
q = read();
init();
for(i = ; i <= q; i++)
{
while ((ch=getchar()) < 'A' || ch > 'Z');
x = read();
y = read();
z = read();
if(ch == 'M') update(x, y, z);
else printf("%d\n", query(x, y, z));
}
return ;
}
[luoguP2801] 教主的魔法(二分 + 分块)的更多相关文章
- BZOJ_3343_教主的魔法_分块+二分查找
BZOJ_3343_教主的魔法_分块+二分查找 题意:教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列被编号为 ...
- P2801 教主的魔法(分块)
P2801 教主的魔法 区间加法,区间查询 显然就是分块辣 维护一个按块排好序的数组. 每次修改依然是整块打标记,零散块暴力.蓝后对零散块重新排序. 询问时整块二分,零散块暴力就好辣 注意细节挺多和边 ...
- BZOJ 3343:教主的魔法(分块)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3343 [题目大意] 给出一个数列,有区间加法操作,询问区间大于等于c的数字个数 [题解 ...
- 【Luogu】P2801教主的魔法(分块)
题目链接 激动qwq.这是我A的第一道分块. 分块之后对块内元素暴力sort.修改的时候对于整块打个标记,查询的时候只需要查C-tag就行了 对于非整块,暴力修改,改完之后sort 对于查询……非整块 ...
- bzoj3343 教主的魔法【分块入门】By cellur925
题意:维护一个数列,给出维护区间加法,询问区间内大于等于某个值的元素个数. 算法:分块.因为本题第二问显然可以用二分的思想,但是这貌似并不符合区间可加性,线段树好像就不好用了呢.所以本蒟蒻学习了分块. ...
- BZOJ 3343 教主的魔法(分块)
题意: 有一个1e6的数组,t次操作:将[l,r]内的值增加w,或者查询[l,r]内的值大于等于add的 思路: 分块,块大小为sqrt(n),每次只需要暴力头尾两块,中间的整块打标记, 对于查询查操 ...
- Luogu2801 教主的魔法 (分块)
与hzw的分块2类似,放vector排序 #include <iostream> #include <cstdio> #include <cstring> #inc ...
- 【BZOJ3343】教主的魔法 分块+二分
Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. 每个人的 ...
- 洛谷P2801 教主的魔法 [分块,二分答案]
题目传送门 教主的魔法 题目描述 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.…….N. ...
随机推荐
- poj2139 Six Degrees of Cowvin Bacon
思路: floyd 实现: #include <iostream> #include <cstdio> #include <cstring> #include &l ...
- vs 2017 下 千万不要装force utf8 这个插件
千万不要装!!! 装了之后,传文件到linux系统下,各种xml和makefile报错(如下) Makefile:1: *** 遗漏分隔符 . 停止
- Bootstrap基本理论
Bootstrap,来自 Twitter,是目前最受欢迎的前段框架.Bootstrap是基于HTML.CSS.JAVASCRIPT的,它简洁灵活,使得Web开发更加快捷 Bootstrap特点:优雅, ...
- MY $MYVIMRC
set nocompatiblesource $VIMRUNTIME/vimrc_example.vim"source $VIMRUNTIME/mswin.vim"behave m ...
- PHP获取时间总结
查询前一年时间戳 mktime(0,0,0,date('m'),date('d'),date('Y')-1); strtotime('-12 month'); 查询前6个月时间戳 mktime(0,0 ...
- iOS逆向实战与工具使用(微信添加好友自动确认)
iOS逆向实战与工具使用(微信添加好友自动确认) 原文链接 源码地址 WeChatPlugin-iOS Mac OS 版微信小助手(远程控制.消息防撤回.自动回复.微信多开) 一.前言 本篇主要实现在 ...
- c# 从DataGridVieew导出到excel
public static bool DataGridViewToExcel(DataGridView dataGridView, bool isShowExcel) { int rowsQty = ...
- react基础语法(二)常用语法如:样式 ,自定义属性,常用表达式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- HDU 5381 The sum of gcd (技巧,莫队算法)
题意:有一个含n个元素的序列,接下来有q个询问区间,对每个询问区间输出其 f(L,R) 值. 思路: 天真单纯地以为是道超级水题,不管多少个询问,计算量顶多就是O(n2) ,就是暴力穷举每个区间,再直 ...
- (转)搭建Spring4.x.x开发环境
http://blog.csdn.net/yerenyuan_pku/article/details/52831306 先去Spring官网下载Spring4.x.x开发包(本人使用的版本是Sprin ...