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--区间加法,区间求和 这个也是很多数据结构完爆的题目线段树入门题,但是练分块我们就要写吗 修改还是与之前类似,只不过我们要维护每 ...
随机推荐
- 【Mysql sql inject】【入门篇】sqli-labs使用 part 4【18-20】
这几关的注入点产生位置大多在HTTP头位置处 常见的HTTP注入点产生位置为[Referer].[X-Forwarded-For].[Cookie].[X-Real-IP].[Accept-Langu ...
- ARMV8 datasheet学习笔记4:AArch64系统级体系结构之Generic timer
1.前言 2.generate timer 2.1 概述 提供了一个系统计数器,用来实时测量流逝的时间: 提供了一个虚拟计数器,用来测量某个虚拟机上流逝的虚拟时间: 定时器,每隔一段时间会触发事件,支 ...
- windows下解压zip包,包含中文解析
#coding=utf8 import os import zipfile import sys,locale # 本来以为需要,结果不需要 # def p(f): # #print '%s.%s() ...
- 001_深度剖析什么是 SLI、SLO和SLA?
前言 SLO和SLA是大家常见的两个名词:服务等级目标和服务等级协议. 云计算时代,各大云服务提供商都发布有自己服务的SLA条款,比如Amazon的EC2和S3服务都有相应的SLA条款.这些大公司的S ...
- 深入理解【缺页中断】及FIFO、LRU、OPT这三种置换算法
缺页中断(英语:Page fault,又名硬错误.硬中断.分页错误.寻页缺失.缺页中断.页故障等)指的是当软件试图访问已映射在虚拟地址空间中,但是目前并未被加载在物理内存中的一个分页时,由中央处理器的 ...
- 微信HTML5页面设计建议
一个HTML5页面从提出到完成上线的流程:> 1.需求方.设计人员.H5实现人员三方共同讨论实现方案 2.设计人员出设计图 3.H5人员按设计图出H5页面 4.需求方评估已实现的H5页面后给 ...
- poj3321 dfs序+树状数组单点更新 好题!
当初听郭炜老师讲时不是很懂,几个月内每次复习树状数组必看的题 树的dfs序映射在树状数组上进行单点修改,区间查询. /* 树状数组: lowbit[i] = i&-i C[i] = a[i-l ...
- python 全栈开发,Day105(路飞其他数据库表结构,立即结算需求)
考试第三部分:Django 16. 列列举你熟悉的Http协议头以及作用.(1分) Accept-Charset: 用于告诉浏览器,客户机采用的编码 Host: 客户机通过这个头告诉服务器,想访问的 ...
- 最近关于mysql的造型,binlog使用,以及阿里云上线数据处理错误导致被处罚的思考
因团队中成员,上线代码时,不小心将数据表中吃掉物理的数据清空,导致被单位处罚,痛定思痛,我们应该如何上线,还需要准备哪些技能? 1.上线时,必须关闭服务,不能一边上线,一边让用户可以继续操作,一边产生 ...
- ubuntu的常用liunx命令
一.基本命令 1.查看Ubuntu版本 $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Descriptio ...