LibreOJ 6282. 数列分块入门 6
题目链接: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的更多相关文章
- LibreOJ 6282 数列分块入门 6(在线插入在线查询)
题解:还是分块,将每个块存入vector,然后在插入的时候就是sqrt(n)级的重构,如果块太大了,暴力将这个块拆开. 代码如下: #include<cmath> #include< ...
- LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)
#6282. 数列分块入门 6 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 1 题目描述 给出 ...
- LibreOJ 6277. 数列分块入门 1 题解
题目链接:https://loj.ac/problem/6277 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字 \( ...
- LibreOJ 6277 数列分块入门 1(分块)
题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include ...
- LibreOJ 6278. 数列分块入门 2 题解
题目链接:https://loj.ac/problem/6278 题目描述 给出一个长为 \(n\) 的数列,以及 \(n\) 个操作,操作涉及区间加法,询问区间内小于某个值 \(x\) 的元素个数. ...
- LOJ#6282. 数列分块入门 6
一个动态的插入过程,还需要带有查询操作. 我可以把区间先分块,然后每个块块用vector来维护它的插入和查询操作,但是如果我现在这个块里的vector太大了,我可能的操作会变的太大,所以这时候我需要把 ...
- LOJ.6282.数列分块入门6(块状链表/分块)
题目链接 1.分块(vector)+重构 //直接上vector(本机还是比较慢的...) 某块size较大时O(n)重构 //注意细节 #include <cmath> #include ...
- LibreOJ 6285. 数列分块入门 9
题目链接:https://loj.ac/problem/6285 其实一看到是离线,我就想用莫队算法来做,对所有询问进行分块,但是左右边界移动的时候,不会同时更新数字最多的数,只是后面线性的扫了一遍, ...
- LibreOJ 6277. 数列分块入门 2
题目链接:https://loj.ac/problem/6278 参考博客:https://blog.csdn.net/qq_36038511/article/details/79725027 这题我 ...
随机推荐
- Android将Log写入文件
为什么要将Log写入文件 运行应用程序的时候,大多数是不会连接着IDE的: 而当应用程序崩溃时,我们需要收集复现步骤,在设备上复现,并进行Debug: 而由于Android手机的多样性,有些问题是某个 ...
- leetcode1016
class Solution(object): def queryString(self, S: str, N: int) -> bool: return all(S.find(bin(i)[2 ...
- requirements.txt 的使用与创建
1. requirements.txt 主要是记录你的python 解释器安装了那些第三方模块,这样好方便项目迁移,自动解决掉项目的依赖关系 2. 网上找的那些关于 requirements 的文档 ...
- linux配置sphinx
1. 配置索引 cd /usr/local/sphinx/etc/ cp sphinx.conf.dist sphinx.conf //备份配置文件,防止改错 vim sphinx.conf 配置文件 ...
- idea 自动导入包和自动将没用的包去除
加快开发效率,除去没用的包,洁癖者必用! 这样设置,就可以自动导入包以及除去没有用到的包
- preparedstatement 为什么可以防止sql注入
有大神总结的很好,,参考文献 http://www.importnew.com/5006.html preparedstatement优势:sql的预编译(数据库层面完成)提升效率. 为什么可以防止s ...
- vue ...mapMutations 的第一个参数默认为 数据对象state
1.实现回调后 路由的跳转 mutationsLoginHeaderBackFun(state,$router) { console.log(state); console.log($router); ...
- 链表有环判断,快慢指针两种方法/合并链表/删除重复元素/二分递归和while
public static boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return fals ...
- byobu session window split
new session: Ctrl + Shift + F2 window: F2 split: Shift/Ctrl + F2 move session: Alt + Up/Down window ...
- 尚硅谷springboot学习22-Thymeleaf入门
Thymeleaf是一种模板引擎,类似于JSP.Velocity.Freemarker