[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. ...
随机推荐
- SOLRJ单机-添加文档,删除,查询操作
单机solrJ不需要占用太多的服务器和资源,本机使用solr-6.3.0,也不需要配置tomcat. 一.新建一个java工程需要依赖的jar包如下: solr-solrj-6.3.0.jar; c ...
- canvas 平移&缩放
1.平移 canvas其实只是一个包装器,真正起着重要作用的部分是2D渲染上下文,这才是我们真正绘制图形的地方. 然而2D渲染上下文是一种基于屏幕的标准绘制平台.它采用屏幕的笛卡尔坐标系统,以左上角( ...
- 一条陌生的出路【过往d心声】
一条陌生的出路 Vashon的心声 人生就像一列车,车上总有形形色色的人穿梭往来.你也可能会在车上遇到很多你以为有缘分的人,但是车也会有停下来的时候,总会有人从人生这列车上上下下,当你下去的时候你挥挥 ...
- java实现单向链表的增、删、改、查
单向链表 作者:vashon package com.ywx.link; /** * 单向链表 * @author vashon * */ public class LinkTest { public ...
- jacob的使用方法
网上一大堆你抄我的,我抄你的,但基本配置都没说清,做个笔记让后来的人少走冤枉路 1.下载最新的jacob,jdk版本一一对应,1.6对应jacob的1.16,1.7对应1.17.... 2.应用程序将 ...
- c# sqlserver连接字符串
odbc: string cnnstring = @"Driver={SQL Server Native Client 11.0};Initial Catalog = sxquadb;ser ...
- RPC(Remote Procedure Call Protocol)远程过程调用协议
RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议的存在 ...
- 如何实现Windows宿主系统和虚拟机ubuntu系统文件互相访问
我的宿主操作系统是Windows 10,使用Oracle的Virtual Box安装了Ubuntu. 因为工作需要我经常得在两个系统之间互相拷贝一些数据,下面是具体步骤,可以实现Windows 10和 ...
- tomcat 安全配置文档
1.配置文档中使用$CATALINA_HOME变量声明为tomcat的安装目录并明确写出了tomcat的配置文件路径,此路径为测试环境的路径,线上系统对应配置文件的路径可能不一样,在进行相关配置时,应 ...
- 【Hive】explain command throw ClassCastException in 2.3.4
参考:https://issues.apache.org/jira/browse/HIVE-21489 (一)问题描述: Hive-2.3.4 执行 explain select * from sr ...