题目链接:https://loj.ac/problem/6282

参考博客:http://www.cnblogs.com/stxy-ferryman/p/8560551.html

这里如果用数组的话元素右移肯定会超时,如果用链表查询时O(n),n次询问就是O(n^2),然后刚刚又瞟了几眼别人的博客,用分块的话主要好像是有查询位置,插入元素,重构三个操作,查询就是找我们要的这个点在第几层的第几个位置(用的是vector),大概是√n的时间复杂度,因为分成了√n块;然后找到位置之后就可以插入,也是√n,因为插入时要把元素右;然后因为极端数据数据有可能只在一个块里插入元素,所以这个块里面的元素可能远远多于其他块,导致查询时候的时间复杂度变成n,所以要把所有元素重新分块,所以重构的时间复杂度是√n,我看他们都是当一个块里的元素大于10*√n,前面10这个系数应该是可以自己看清况给的,这样的话重构次数是小于√n次的,整体的时间复杂度不太会加,^_^,反正就是比n^2低好多就是了...。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 100005
/*struct point{
int u,w;
};
bool operator <(const point &s1,const point &s2)
{
if(s1.w!=s2.w)
return s1.w>s2.w;
else
return s1.u>s2.u;
}*/
int lump[maxn],a[maxn*];//lump数组用不到,可以不要,a数组是等下重构时用来存所有元素的
vector<int>ve[];//存每一层的元素
int n,m,k,t,block,Max; //Max是用来存最多有多少层
pair<int,int> query(int l)//这个函数是用来寻找第l个元素在第几层第几个,返回一个pair<int,int>类型
{ //它的fist表示层数,second表示第几个,vector里元素从0开始
int pos=;
while(l>ve[pos].size())
{
l-=ve[pos].size();
pos++;
}
return make_pair(pos,l-);
}
void rebuild()//重构操作
{
int top=;
for(int i=;i<=Max;i++)
{
for(int j=;j<ve[i].size();j++)
{
a[++top]=ve[i][j];//把所有元素存起来
}
ve[i].clear();//记得清空
}
int block1=sqrt(top);//新的块的大小
for(int i=;i<=top;i++)
{
ve[(i-)/block1+].push_back(a[i]);
}
Max=(top-)/block+;
}
void insert(int l,int r)
{
pair<int,int>w=query(l);//找到位置
ve[w.first].insert(ve[w.first].begin()+w.second,r);//插入元素
if(ve[w.first].size()>block*)//如果块太大就重构
rebuild();
}
int find(int l,int r)
{
pair<int,int>w=query(r);
return ve[w.first][w.second];
}
int main()
{
scanf("%d",&n);
block=sqrt(n);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
lump[i]=(i-)/block+;
ve[lump[i]].push_back(x);
}
Max=(n-)/block+;
for(int j=;j<=n;j++)
{
int op,l,r,c;
scanf("%d%d%d%d",&op,&l,&r,&c);
if(!op)
insert(l,r);
else
{
int ans=find(l,r);
printf("%d\n",ans);
}
}
return ;
}

LibreOJ 6282. 数列分块入门 6的更多相关文章

  1. LibreOJ 6282 数列分块入门 6(在线插入在线查询)

    题解:还是分块,将每个块存入vector,然后在插入的时候就是sqrt(n)级的重构,如果块太大了,暴力将这个块拆开. 代码如下: #include<cmath> #include< ...

  2. LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)

    #6282. 数列分块入门 6 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 1   题目描述 给出 ...

  3. LibreOJ 6277. 数列分块入门 1 题解

    题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 \( ...

  4. LibreOJ 6277 数列分块入门 1(分块)

    题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...

  5. LibreOJ 6278. 数列分块入门 2 题解

    题目链接:https://loj.ac/problem/6278 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的元素个数. ...

  6. LOJ#6282. 数列分块入门 6

    一个动态的插入过程,还需要带有查询操作. 我可以把区间先分块,然后每个块块用vector来维护它的插入和查询操作,但是如果我现在这个块里的vector太大了,我可能的操作会变的太大,所以这时候我需要把 ...

  7. LOJ.6282.数列分块入门6(块状链表/分块)

    题目链接 1.分块(vector)+重构 //直接上vector(本机还是比较慢的...) 某块size较大时O(n)重构 //注意细节 #include <cmath> #include ...

  8. LibreOJ 6285. 数列分块入门 9

    题目链接:https://loj.ac/problem/6285 其实一看到是离线,我就想用莫队算法来做,对所有询问进行分块,但是左右边界移动的时候,不会同时更新数字最多的数,只是后面线性的扫了一遍, ...

  9. LibreOJ 6277. 数列分块入门 2

    题目链接:https://loj.ac/problem/6278 参考博客:https://blog.csdn.net/qq_36038511/article/details/79725027 这题我 ...

随机推荐

  1. Gson 解决时间解析问题

    异常: at org.eclipse.jdt.) at org.eclipse.jdt.) Caused by: java.text.ParseException: Failed to parse d ...

  2. leetcode1004

    class Solution: def getMax(self,B:'List[int]'): n = len(B) maxlen = 0 curlen = 0 for i in range (n): ...

  3. leetcode983

    public class Solution { public int MincostTickets(int[] days, int[] costs) { ; ; ]; dp[] = ; ; i < ...

  4. Shell 编程(循环)

    for in 循环语句 #!/bin/bash for x in one two three four do echo number $x done 例:取出passwd中每一行name 并输出 he ...

  5. ES6 模块导入import 导出export 和module.export

    ES6中新增了模块的导入和导出功能 在实际过程中可以使用 import 和 export 对模块进行导入和导出操作,具体如下 1. 名字导入/导出  (导入名字必须与导出的一致,导入时需要用花括号) ...

  6. mysql存储过程使用游标循环插入数据

    DELIMITER $$ DROP PROCEDURE IF EXISTS `procedure_course`$$ CREATE DEFINER=`root`@`localhost` PROCEDU ...

  7. UI5-学习篇-8-本地SAP WEB IDE开发

    1.本地SAP WEB IDE下载 UI5-学习篇-3-Local SAP WEB IDE下载 2.启动Orion服务 解压SAP WEB IDE文件后,双击Orion应用程序启动服务,如下图: 服务 ...

  8. python语言中的数据类型之字典

    数据类型 字典类型dict 用途:记录多个值,列表是索引对应值,而字典是key对应值,其中key对value有描述性 定义方式:在{ }用逗号分隔开多个元素,每个元素都是key:value形式,其中k ...

  9. RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World(转载)

    RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World 一.简介 RabbitMQ是一个消息的代理器,用于接收和发送消息,你可以这样想,他就是一个邮局,当您把需要寄送的邮件投递到 ...

  10. Linux date命令使用方法

    date命令用来显示或设定以及计算系统的日期和时间.本文主要描述date命令的基本语法和工作中常用的使用方法. date命令语法 用法:date [OPTION]... [+FORMAT] 常用参数: ...