LOJ.6282.数列分块入门6(块状链表/分块)
题目链接
1.分块(vector)+重构
//直接上vector(本机还是比较慢的...) 某块size较大时O(n)重构
//注意细节
#include <cmath>
#include <cstdio>
#include <cctype>
#include <vector>
#define gc() getchar()
#define pb push_back
typedef long long LL;
const int N=1e5+5;
int n,size,tmp[N<<1],bel;
std::vector<int> v[500];
std::vector<int>::iterator it;
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
inline int Get_Pos(int &p)
{
for(int i=1; i<=bel; ++i)
if((p-=v[i].size())<=0) {p+=v[i].size(); return i;}
}
void Rebuild()
{
int tot=0;
for(int i=1; i<=bel; ++i)
{
for(it=v[i].begin(); it!=v[i].end(); ++it) tmp[++tot]=*it;
v[i].clear();
}
size=sqrt(tot);
for(int i=1; i<=tot; ++i) bel=(i-1)/size+1, v[bel].pb(tmp[i]);
}
void Insert(int p,int val)
{
int id=Get_Pos(p);
v[id].insert(v[id].begin()+p-1,val);
if(v[id].size()>size*15) Rebuild();
}
int main()
{
n=read(), size=sqrt(n);
for(int i=1; i<=n; ++i) bel=(i-1)/size+1,v[bel].pb(read());
for(int opt,l,r,c,id,i=1; i<=n; ++i)
{
opt=read(),l=read(),r=read(),c=read();
if(opt) id=Get_Pos(r),printf("%d\n",v[id][r-1]);
else Insert(l,r);
}
return 0;
}
2.块状链表
#include <cmath>
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e5+5;
int n,size,H[N],nxt[N],nxtv[N<<1],A[N<<1],sz[N];//二倍数组!mdzzC++数组越界各种奇葩错误(这指针无语)
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
inline int New_Node()
{
static int cnt=n;
return ++cnt;
}
inline int New_Block()
{
static int cnt=(n-1)/size+1;
return ++cnt;
}
void Init()
{
for(int i=1; i<=n; ++i) A[i]=read();
int tot=(n-1)/size+1;
H[0]=1;
for(int now=0,i=1; i<tot; ++i)//块整体的链表
H[i]=(i-1)*size+1, nxt[i]=i+1, sz[i]=size;
sz[tot]=n-(tot-1)*size, H[tot]=(tot-1)*size+1;
for(int i=1,tmp=i*size; i<=tot; tmp=++i*size)//块内链表
for(int j=(i-1)*size+1; j<tmp; ++j)
nxtv[j]=j+1;
}
int Get_Pos(int &p)
{
for(int i=H[0]; i; i=nxt[i])
if((p-=sz[i])<=0) {p+=sz[i]; return i;}
}
int Query(int p)
{
int id=Get_Pos(p);
for(int i=H[id]; i; i=nxtv[i])
if(!--p) return A[i];
}
void Insert(int p,int v)
{
int id=Get_Pos(p),pos=New_Node();
A[pos]=v, ++sz[id];
// printf("I pos:%d id:%d p:%d size:%d stdsz:%d sz[id]:%d\n",pos,id,p,size*(id-1)+p,size,sz[id]);
if(!p) nxtv[pos]=H[id], H[id]=pos;
else
for(int i=H[id]; i; i=nxtv[i])
if(!--p) {nxtv[pos]=nxtv[i], nxtv[i]=pos; break;}
if(sz[id] > size<<1)//2倍比较合适
{
p=size;
for(int i=H[id]; i; i=nxtv[i])
if(!(--p)) {pos=nxtv[i], nxtv[i]=0; break;}
int posb=New_Block();
H[posb]=pos, nxt[posb]=nxt[id], nxt[id]=posb, sz[posb]=sz[id]-size, sz[id]=size;
}
}
//void Print()
//{
// puts("Output:");
// for(int i=H[0]; i; i=nxt[i])
// for(int j=H[i]; j; j=nxtv[j])
// printf("%d ",A[j]);
// putchar('\n');
//}
int main()
{
n=read(), size=sqrt(n);
Init();
for(int opt,l,r,c,i=1; i<=n; ++i)
{
opt=read(),l=read(),r=read(),c=read();
if(opt) printf("%d\n",Query(r));
else Insert(l-1,r);
}
return 0;
}
LOJ.6282.数列分块入门6(块状链表/分块)的更多相关文章
- LOJ #6282. 数列分块入门 6-分块(单点插入、单点查询、数据随机生成)
#6282. 数列分块入门 6 内存限制:256 MiB时间限制:500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: hzwer 提交提交记录统计测试数据讨论 1 题目描述 给出 ...
- 【函数式权值分块】【块状链表】bzoj3065 带插入区间K小值
显然是块状链表的经典题.但是经典做法的复杂度是O(n*sqrt(n)*log^2(n))的,出题人明确说了会卡掉. 于是我们考虑每个块内记录前n个块的权值分块. 查询的时候差分什么的,复杂度就是O(n ...
- LOJ#6282. 数列分块入门 6
一个动态的插入过程,还需要带有查询操作. 我可以把区间先分块,然后每个块块用vector来维护它的插入和查询操作,但是如果我现在这个块里的vector太大了,我可能的操作会变的太大,所以这时候我需要把 ...
- 题解【loj6277】数列分块入门1
题目描述 给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字\(n\). 第二行输入\(n\)个数字,第\(i\)个数字为\(a_{i}\) ...
- ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)
题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...
- 块状链表 bzoj 3343教主的魔法
//块状链表//分块排序,然后每次查找时在暴力查找头和尾两个块.//中间那些块,因为有序所以只需2分查找即可.我用的是lower_pound();//插入是,也是头和尾暴力插入,中间那些加到一个累计里 ...
- [Loj] 数列分块入门 1 - 9
数列分块入门 1 https://loj.ac/problem/6277 区间加 + 单点查询 #include <iostream> #include <cstdio> #i ...
- LOJ——#6277. 数列分块入门 1
~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法——分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...
- 数列分块入门九题(二):LOJ6280~6282
Preface 个人感觉这中间的三题是最水的没有之一 数列分块入门 4--区间加法,区间求和 这个也是很多数据结构完爆的题目线段树入门题,但是练分块我们就要写吗 修改还是与之前类似,只不过我们要维护每 ...
随机推荐
- 【python图像处理】图像的缩放、旋转与翻转
[python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...
- OA协同办公软件
OA协同办公软件: 泛微软件. 九思软件. 华天动力. 万户OA.:北京万户网络技术有限公司创立于1998年2月,是北京华宇软件股份有限公司(股票简称:“华宇软件”,股票代码:300271)的全资子公 ...
- [BZOJ3295] [Cqoi2011]动态逆序对(带修改主席树)
题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序 ...
- Python-HTML 最强标签分类
编程: 使用(展示)数据 存储数据 处理数据 前端 1. 前端是做什么的? 2. 我们为什么要学前端? 3. 前端都有哪些内容? 1. HTML 2. CSS 3. JavaScript 4.jQue ...
- vue系列之项目打包
vue完成项目后,如何打包成静态文件,并且用Node调试 打包 1.修改config里面的index.js里面的productionSourceMap为false,默认情况是true(true代表打包 ...
- OneNET麒麟座应用开发之四:数据上传测试
已经测试过OneNET麒麟座开发板了,这次来尝试与OneNET的连接和数据上传.这也是我们测试这块开发办的主要原因,因为在十几种我们有这种将分散的采集点数据上传到后台的需求. 先看看麒麟座这块开发板, ...
- Windows环境selenium+Python环境配置
1.安装Python 访问Python官方网站. 根据自己的操作系统32/64 位,选择相应的版本. 安装过程我就不详细描述了,动动手指头,Google一下,你就知道.我的安装目录为:C:\Pytho ...
- oracle中主键自增
oracle中主键自增 下面用一个例子来说明自增主键的创建: 1.建用户数据表 drop table dectuser; create table dectuser( userid integer p ...
- div展开与收起(鼠标点击)
效果图: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...
- 【BZOJ4927】第一题 双指针+DP
题解: 虽然是过了,不过做的十分智障 首先是有 2根 2 1 1 , 3根 1 1 1 这两种方法 然后考虑2 2 1 1 two-point-two没啥好说的 3 1 1 1 我很智障的以为数据范围 ...