题目链接

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(块状链表/分块)的更多相关文章

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

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

  2. 【函数式权值分块】【块状链表】bzoj3065 带插入区间K小值

    显然是块状链表的经典题.但是经典做法的复杂度是O(n*sqrt(n)*log^2(n))的,出题人明确说了会卡掉. 于是我们考虑每个块内记录前n个块的权值分块. 查询的时候差分什么的,复杂度就是O(n ...

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

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

  4. 题解【loj6277】数列分块入门1

    题目描述 给出一个长为\(n\)的数列,以及\(n\)个操作,操作涉及区间加法,单点查值. 输入格式 第一行输入一个数字\(n\). 第二行输入\(n\)个数字,第\(i\)个数字为\(a_{i}\) ...

  5. ZOJ 2112 Dynamic Rankings(动态区间第 k 大+块状链表)

    题目大意 给定一个数列,编号从 1 到 n,现在有 m 个操作,操作分两类: 1. 修改数列中某个位置的数的值为 val 2. 询问 [L, R] 这个区间中第 k 大的是多少 n<=50,00 ...

  6. 块状链表 bzoj 3343教主的魔法

    //块状链表//分块排序,然后每次查找时在暴力查找头和尾两个块.//中间那些块,因为有序所以只需2分查找即可.我用的是lower_pound();//插入是,也是头和尾暴力插入,中间那些加到一个累计里 ...

  7. [Loj] 数列分块入门 1 - 9

    数列分块入门 1 https://loj.ac/problem/6277 区间加 + 单点查询 #include <iostream> #include <cstdio> #i ...

  8. LOJ——#6277. 数列分块入门 1

    ~~推荐播客~~ 「分块」数列分块入门1 – 9 by hzwer 浅谈基础根号算法——分块 博主蒟蒻,有缘人可直接观摩以上大佬的博客... #6277. 数列分块入门 1 题目大意: 给出一个长为 ...

  9. 数列分块入门九题(二):LOJ6280~6282

    Preface 个人感觉这中间的三题是最水的没有之一 数列分块入门 4--区间加法,区间求和 这个也是很多数据结构完爆的题目线段树入门题,但是练分块我们就要写吗 修改还是与之前类似,只不过我们要维护每 ...

随机推荐

  1. 提高CPU使用率100%

    直接上脚本: #!/bin/bash while true do echo 2^2^20 | bc & >/dev/null done 查看CPU使用率用top命令即可 释放CPU: p ...

  2. Linux文件系统3--打开文件

    1.前言 本文所述关于文件管理的系列文章主要是对陈莉君老师所讲述的文件系统管理知识讲座的整理. Linux可以支持不同的文件系统,它源于unix文件系统,也是unix文件系统的一大特色. 本文将以不同 ...

  3. Python3学习笔记26-unittest模块

    unittest单元测试框架,主要由四部分组成:测试固件.测试用例.测试套件.测试执行器 测试固件(test fixture) 测试固件有两部分,执行测试前的准备部分setUp(),测试执行完后的清扫 ...

  4. Sql 插入自定义主键

    在遇到数据库设计是自增的主键,且需要插入自定义的主键Id时,这个时候如果直接Insert的话,将会发生错误,错误提示信息: 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'XXX' ...

  5. centos6下通用二进制安装mysql5.5.33

    mysql5.5通用二进制格式安装方法 1.解压到 /usr/local 目录 # tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local 2 ...

  6. js动态添加未知新属性

    1 前言 由于项目需要,需要实现获取服务器不同网卡扫局域网中的某种类型设备,然而不同服务器的网卡个数是不相同的,从而需要动态增加未知属性来统计不同网卡扫到的设备个数. 2 代码 function ni ...

  7. jquery submit ie6下失效的原因分析及解决方法

    ie6中, $('a.btn').click(function(){ form.submit(); }) 点击失效: 分析: 微软低版本浏览器会先执行link标签的自身事件也就是href事件,这样就中 ...

  8. SPLAY,LCT学习笔记(四)

    前三篇好像变成了SPLAY专题... 这一篇正式开始LCT! 其实LCT就是基于SPLAY的伸展操作维护树(森林)连通性的一个数据结构 核心操作有很多,我们以一道题为例: 例:bzoj 2049 洞穴 ...

  9. 步步为营-35-SQL语言基础

    SQL 结构化查询语言(Structured Query Language) DDL DML DCL 在此不再对其进行详细解释 1 DDL 数据库定义语言 1.1 创建数据库脚本 --DDL crea ...

  10. Nginx 响应状态

    ngx.status = ngx.HTTP_CONTINUE (100) (first added in the v0.9.20 release)ngx.status = ngx.HTTP_SWITC ...