题目链接

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. Django 利用管理器实现文章归档

    Django管理器:class Manager 管理器是Django的模型进行数据库查询的接口,Django应用的每个模型都拥有至少一个管理器.默认情况下,Django为每个模型类添加一个名为obje ...

  2. Linux Kernel 代码艺术——编译时断言【转】

    转自:http://www.cnblogs.com/hazir/p/static_assert_macro.html 本系列文章主要写我在阅读Linux内核过程中,关注的比较难以理解但又设计巧妙的代码 ...

  3. Ubuntu 16.04配置国内高速apt-get更新源【转】

    转自:https://blog.csdn.net/twang0x80/article/details/79782753 Ubuntu 16.04下载软件速度有点慢,因为默认的是从国外下载软件,那就更换 ...

  4. OA协同办公软件

    OA协同办公软件: 泛微软件. 九思软件. 华天动力. 万户OA.:北京万户网络技术有限公司创立于1998年2月,是北京华宇软件股份有限公司(股票简称:“华宇软件”,股票代码:300271)的全资子公 ...

  5. windows系统上搭建redis集群哨兵及主从复制

    搭建master 修改redis配置redis.windows.conf: 修改监听端口:  port 26379 修改绑定IP: bind 127.0.0.1 添加redis日志:logfile & ...

  6. Filter功能

    在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest .根据需要检查HttpServletRequest,也可以修改HttpServletR ...

  7. js 、c# 编码解码

    escape不编码字符有69个:*,+,-,.,/,@,_,0-9,a-z,A-Z encodeURI不编码字符有82个:!,#,$,&,',(,),*,+,,,-,.,/,:,;,=,?,@ ...

  8. 重装系统windows

    1 boot没有usb启动选项,驱动没加载好,先进入xp系统正确安装usb驱动,重启 2 file not fount bootmgr 用pe自带修复程序修复,修复驱动盘符为最小那个,非c盘 3 wi ...

  9. appium运行报错java.net.SocketException: socket write error

    这个错我调了 快两天一点头绪没有,脚本正常跑没问题,但是就是控制台输出信息报错,没法定位问题在哪.报错如图: 虽然这个报错不影响测试结果,但是本人有强迫症,一定要查出究竟: 我的尝试: 1.那天试验, ...

  10. [学习笔记]Javascript采用二进制浮点数和四舍五入的错误

    1.样例 var a = .3 - .2 //0.09999999999999998 var b = .2 - .1 //0.1 a == b //false 出现这样的原因在于 1.Javascri ...