题解【loj6277】数列分块入门1
题目描述
给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,单点查值。
输入格式
第一行输入一个数字\(n\)。
第二行输入\(n\)个数字,第\(i\)个数字为\(a_{i}\),以空格隔开。
接下来输入\(n\)行询问,每行输入四个数字\(opt\)、\(l\)、\(r\)、\(c\),以空格隔开。
若\(opt = 0\),表示将位于\([l, r]\)的之间的数字都加\(c\)。
若\(opt = 1\),表示询问\(a_{r}\)的值(\(l\)和\(c\)忽略)。
输出格式
对于每次询问,输出一行一个数字表示答案。
样例
样例输入
4
1 2 2 3
0 1 3 1
1 0 1 0
0 1 2 2
1 0 2 0
样例输出
2
5
数据范围与提示
对于所有的数据,\(1 \leq n \le 50000\) ,\(-2^{31} \leq others、ans \le 2_{31} - 1\) 。
题解
这是一道很好的分块入门题。
所谓分块,就是一种通过将一个序列分成多块后,在每块上打标记以实现快速区间修改,区间查询的一种算法。其均摊时间复杂度为\(\Theta\sqrt{n}\)。
在一般情况下,每个块的长度都为\(\sqrt{n}\)。
分块,被尊称为优雅的暴力,因此它的代码难度也不算高。总之,比线段树、树状数组等毒瘤数据结构的代码难度低。
我们需要建立三个数组:
- \(a[]\),为题目中输入的序列;
- \(b[]\),记录每个序列中的每个数在那一块;
- \(add[]\),为序列的标记数组。
话不多说,上代码。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>//头文件准备
using namespace std;//使用标准名字空间
inline int gi()//快速读入
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-')f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
}
int a[50005], b[50005], add[50005], len, n, m;//a[],b[],add[]的意思如分析,len为每一块的长度,n为序列长度,m为询问个数,在本题中=n。
inline void modify(int l, int r, int x)//区间修改的自定义函数
{
for (int i = l; i <= min(r, b[l] * len); i++) a[i] = a[i] + x;//增加序列中的数
if (b[l] != b[r])//如果要修改的不在同一个块中
{
for (int i = (b[r] - 1) * len + 1; i <= r; i++) a[i] = a[i] + x;//继续增加序列中的数
}
for (int i = b[l] + 1; i <= b[r] - 1; i++) add[i] = add[i] + x;//给区间内的数增加标记
}
int main()//进入主函数
{
n = gi();//输入元素个数
len = sqrt(n);//求出每个块的长度
for (int i = 1; i <= n; i++) a[i] = gi();//输入序列中的数
for (int i = 1; i <= n; i++) b[i] = (i - 1) / len + 1;//求出序列中的数分别属于哪一个块
for (int p = 1; p <= n; p++)
{
int fl = gi(), l = gi(), r = gi(), w = gi();//输入操作的描述
if (!fl)//如果是修改
{
modify(l, r, w);//修改区间内的数
}
else//否则就是求出某个数
{
printf("%d\n", a[r] + add[b[r]]);//输出这个位置的数的标记和它在序列中原本的数的和
}
}
return 0;//完美结束
}
题解【loj6277】数列分块入门1的更多相关文章
- 题解——loj6277 数列分块入门1(分块)
分块裸题 然后就是记得左右边界处理和分块的初始化 忘了初始化会被卡成暴力 #include <cstdio> #include <algorithm> #include < ...
- 题解——loj6281 数列分块入门5 (分块)
分块 若块内最大值为0或1,则不用再开方 然后暴力修改 可以证明,如果开方后向下取整,则最多开方4次一个数就会变成0或1 #include <cstdio> #include <cm ...
- 题解——loj6280 数列分块入门4 (分块)
分块维护一个区间和 然后记得更新的时候左边角块的tag不要打错到右边角块 #include <cstdio> #include <algorithm> #include < ...
- [LOJ6277]数列分块入门 1
题目大意: 给你一个长度为$n(n\leq 50000)$的序列$A$,支持进行以下两种操作: 1.将区间$[l,r]$中所有数加上$c$: 2.询问$A_r$的值.思路: 分块. 对于整块的数据打标 ...
- loj6277 数列分块入门题1
裸题分块. #include <bits/stdc++.h> using namespace std; ],b[],n,m,t1,t2,t3,t4,sq; int main(){ ios: ...
- 题解——loj6279 数列分块入门3 (分块)
用set维护有序序列 或许sort也可以,但这题的前驱定义是严格小于 所以要去重 然后就是记得自己打的加法tag在query的时候一定要算上 话说这题数据有点fake啊忘了查询算上自己的标记了还有70 ...
- 题解——loj6278 数列分块入门2 (分块)
查询小于k的值 注意lower_bound一定要减去查找的起始位置得到正确的位置 调了快两天 淦 #include <cstdio> #include <algorithm> ...
- LOJ6277~6285 数列分块入门
Portals 分块需注意的问题 数组大小应为,因为最后一个块可能会超出的范围. 当操作的区间在一个块内时,要特判成暴力修改. 要清楚什么时候应该+tag[t] 数列分块入门 1 给出一个长为的数列, ...
- 数列分块入门九题(一):LOJ6277~6279
Preface 分块,一个神奇的暴力算法.可以把很多\(O(n^2)\)的数据结构题的暴力优化到常数极小的\(O(n\sqrt n)\).当一些毒瘤题无法用线段树,主席树,平衡树,树状数组...... ...
- LibreOJ6279. 数列分块入门 3 题解
题目链接:https://loj.ac/problem/6279 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的前驱(比其 ...
随机推荐
- python的for循环的神奇之处
python的for循环太神奇了: 你可以编写这样的语句: for i in range(10) : j= i**2 print(j) 你也可以编写这样的语句: with open('/path/to ...
- 网络中的 TCP/IP
TCP/IP OSI的“实现”:TCP/IP OSI七层模型 TCP/IP概念层模型 功能 TCP/IP协议族 应用层 应用层 文件传输.电子邮件.文件服务.虚拟终端 FTP,HTTP,SMTP,SN ...
- MySQL的操作数据库SQL语法
MySQL的操作数据库SQL语法 顺序:操作数据库 > 操作数据库中的表 > 操作数据库中的表的数据 MySQL不区分大小写字母 1. 操作数据库 1.创建数据库 2.删除数据库 3.使用 ...
- 数据结构KMP算法中手算next数组
总结一下今天的收获(以王道数据结构书上的为例子,虽然我没看它上面的...):其中竖着的一列值是模式串前缀和后缀最长公共前缀. 最后求得的结果符合书上的结果,如果是以-1开头的话就不需要再加1,如果是以 ...
- Hdu2099 整除的尾数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2099 Problem Description 一个整数,只知道前几位,不知道末二位,被另一个整数除尽了 ...
- vue.js 的cdn 链接的引用地址
引用地址有两种一种完整版,一种压缩版效果是一样的 https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js https://cdn.bootcss.com ...
- 连接数据库报错:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
报错: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.soc ...
- MyEclipse-2017破解过程
下载 myeclipse2017百度云下载路径: 链接:https://pan.baidu.com/s/1wQYwO2zrUvbbUcjCB5B8IQ 密码:6igu myeclipse2017破解文 ...
- Linux - pip 安装使用说明
简介 pip类似RedHat里面的yum,安装Python包非常方便.本节详细介绍pip的安装.以及使用方法 方案一 wget https://bootstrap.pypa.io/get-pip.py ...
- jdbc url的若干参数
参数名称 参数说明 缺省值 最低版本要求 user 数据库用户名,用于连接数据库 无 所有版本 password 用户密码(用于连接数据库) 无 所有版本 useUnicode 是否使用Unicode ...