【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor 块状链表模板题
2016-06-18 当时关于块状链表的想法是错误的,之前维护的是一个动态的$\sqrt{n}$,所以常数巨大,今天才知道原因TwT,请不要参照这个程序为模板!!!
模板题水啊水~~~
第一次写块状链表,先写一个模板题(⊙o⊙)
块状链表虽然效率大概在O(n√n),但它几乎没有常数,相比较理论上复杂度较快的O(nlogn)的Splay还是要快,因为Splay常数太大啦!感觉比较笨重。也许这就是许多OIer热衷分块的原因吧。
BZOJ 1507(因为O2优化,没有内存池)
- #include<cmath>
- #include<queue>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #define for1(i,a,n) for(int i=(a);i<=(n);++i)
- #define for2(i,a,n) for(int i=(a);i<(n);++i)
- #define for3(i,a,n) for(int i=(a);i>=(n);--i)
- #define for4(i,a,n) for(int i=(a);i>(n);--i)
- #define CC(i,a) memset(i,a,sizeof(i))
- using namespace std;
- int now=0,min_tot=0,max_tot=0,tot=0,sq;
- struct BLOCK{
- BLOCK();
- BLOCK *next;
- char c[100003];
- int size;
- }*head,*null;
- BLOCK::BLOCK(){next=null;size=0;}
- inline void build(){
- null=new BLOCK;
- *null=BLOCK();
- head=new BLOCK;
- }
- inline BLOCK *find(int &k){
- BLOCK *r=head;
- while (k-r->size>0&&r->next!=null) k-=r->size,r=r->next;
- return r;
- }
- inline void cut(BLOCK *r,int pos){
- BLOCK *k=new BLOCK;
- k->size=r->size-pos;
- for1(i,pos+1,r->size) k->c[i-pos]=r->c[i];
- r->size=pos;
- k->next=r->next;
- r->next=k;
- }
- inline void merge(BLOCK *r){
- if (r->next==null) return;
- BLOCK *k=r->next;
- for1(i,1,k->size) r->c[r->size+i]=k->c[i];
- r->size+=k->size;
- r->next=k->next;
- delete k;
- }
- inline void balance(){
- BLOCK *r=head;
- sq=floor(sqrt(tot)); min_tot=sq/2; max_tot=sq*2;
- while (r!=null){
- if (r->size<min_tot) if (r->next==null) return; else {merge(r); continue;}
- else if (r->size>max_tot) {cut(r,r->size/2); continue;}
- r=r->next;
- }
- }
- inline void work1(int x){
- int pnow=now; BLOCK *r=find(pnow),*k=new BLOCK,*sta=k;
- cut(r,pnow);
- for1(i,1,x){
- char cs=getchar();
- while (cs=='\n') cs=getchar();
- k->size++; k->c[k->size]=cs;
- if (k->size>=sq){
- k->next=new BLOCK;
- k=k->next;
- }
- }k->next=r->next;r->next=sta;
- }
- inline void work2(int x){
- int pnow=now; BLOCK *r=find(pnow);
- if (x<=r->size-pnow){
- cut(r,pnow); cut(r->next,x);
- BLOCK *xx=r->next;
- r->next=r->next->next;
- delete xx;
- return;
- }
- x-=r->size-pnow;
- cut(r,pnow);
- BLOCK *xy=r->next;
- r->next=r->next->next;
- delete xy;
- while (x-r->next->size>0&&r->next!=null){
- x-=r->next->size;
- BLOCK *xx=r->next;
- r->next=r->next->next;
- delete xx;
- }cut(r->next,x);
- BLOCK *xx=r->next;
- r->next=r->next->next;
- delete xx;
- }
- inline void work3(int x){
- int pnow=now; BLOCK *r=find(pnow);
- if (x<=r->size-pnow){for1(i,pnow+1,pnow+x) putchar(r->c[i]); return;}
- for1(i,pnow+1,r->size) putchar(r->c[i]);
- x-=r->size-pnow; r=r->next;
- while (x-r->size>0&&r!=null){
- for1(i,1,r->size) putchar(r->c[i]);
- x-=r->size; r=r->next;
- }for1(i,1,x)putchar(r->c[i]);
- }
- int main(){
- build();
- int n;scanf("%d\n",&n);
- while (n--){
- char str=getchar(),st=getchar();
- int x;
- switch(str){
- case 'I':
- while (st!=' ') st=getchar();
- scanf("%d",&x); tot+=x; sq=floor(sqrt(tot)); min_tot=sq/2; max_tot=sq*2;
- work1(x);
- balance();
- scanf("\n");
- break;
- case 'M':
- while (st!=' ') st=getchar();
- scanf("%d\n",&now);
- break;
- case 'D':
- while (st!=' ') st=getchar();
- scanf("%d\n",&x); work2(x);
- tot-=x; balance();
- break;
- case 'G':
- while (st!=' ') st=getchar();
- scanf("%d\n",&x); work3(x); printf("\n");
- break;
- case 'P':
- now--;st=getchar();st=getchar();st=getchar();
- break;
- case 'N':
- now++;st=getchar();st=getchar();st=getchar();
- break;
- }
- }
- return 0;
- }
Tyvj P2388(Windows下评测的new和delete慢得飞起,所以写了个内存池)
- #include<cmath>
- #include<queue>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #define for1(i,a,n) for(int i=(a);i<=(n);++i)
- #define for2(i,a,n) for(int i=(a);i<(n);++i)
- #define for3(i,a,n) for(int i=(a);i>=(n);--i)
- #define for4(i,a,n) for(int i=(a);i>(n);--i)
- #define CC(i,a) memset(i,a,sizeof(i))
- using namespace std;
- int now=0,min_tot=0,max_tot=0,tot=0,sq;
- struct BLOCK{
- BLOCK();
- BLOCK *next;
- char c[10003];
- int size;
- }*head,*null,pool[10003];
- int top=0;
- BLOCK::BLOCK(){next=null;size=0;}
- inline BLOCK *newBLOCK(){
- BLOCK *t=&pool[top++];
- t->next=null; t->size=0;
- return t;
- }
- inline void build(){
- null=newBLOCK();
- null->next=null; null->size=0;
- head=newBLOCK();
- }
- inline BLOCK *find(int &k){
- BLOCK *r=head;
- while (k-r->size>0&&r->next!=null) k-=r->size,r=r->next;
- return r;
- }
- inline void cut(BLOCK *r,int pos){
- BLOCK *k=newBLOCK();
- k->size=r->size-pos;
- for1(i,pos+1,r->size) k->c[i-pos]=r->c[i];
- r->size=pos;
- k->next=r->next;
- r->next=k;
- }
- inline void merge(BLOCK *r){
- if (r->next==null) return;
- BLOCK *k=r->next;
- for1(i,1,k->size) r->c[r->size+i]=k->c[i];
- r->size+=k->size;
- r->next=k->next;
- //delete k;
- }
- inline void balance(){
- BLOCK *r=head;
- sq=floor(sqrt(tot)); min_tot=sq/2; max_tot=sq*2;
- while (r!=null){
- if (r->size<min_tot) if (r->next==null) return; else {merge(r); continue;}
- else if (r->size>max_tot) {cut(r,r->size/2); continue;}
- r=r->next;
- }
- }
- inline void work1(int x){
- int pnow=now; BLOCK *r=find(pnow),*k=newBLOCK(),*sta=k;
- cut(r,pnow);
- for1(i,1,x){
- char cs=getchar();
- while (cs=='\n') cs=getchar();
- k->size++; k->c[k->size]=cs;
- if (k->size>=sq){
- k->next=newBLOCK();
- k=k->next;
- }
- }k->next=r->next;r->next=sta;
- }
- inline void work2(int x){
- int pnow=now; BLOCK *r=find(pnow);
- if (x<=r->size-pnow){
- cut(r,pnow); cut(r->next,x);
- BLOCK *xx=r->next;
- r->next=r->next->next;
- //delete xx;
- return;
- }
- x-=r->size-pnow;
- cut(r,pnow);
- BLOCK *xy=r->next;
- r->next=r->next->next;
- //delete xy;
- while (x-r->next->size>0&&r->next!=null){
- x-=r->next->size;
- BLOCK *xx=r->next;
- r->next=r->next->next;
- //delete xx;
- }cut(r->next,x);
- BLOCK *xx=r->next;
- r->next=r->next->next;
- //delete xx;
- }
- inline void work3(int x){
- int pnow=now; BLOCK *r=find(pnow);
- if (x<=r->size-pnow){for1(i,pnow+1,pnow+x) putchar(r->c[i]); return;}
- for1(i,pnow+1,r->size) putchar(r->c[i]);
- x-=r->size-pnow; r=r->next;
- while (x-r->size>0&&r!=null){
- for1(i,1,r->size) putchar(r->c[i]);
- x-=r->size; r=r->next;
- }for1(i,1,x)putchar(r->c[i]);
- }
- int main(){
- build();
- int n;scanf("%d\n",&n);
- while (n--){
- char str=getchar(),st=getchar();
- int x;
- switch(str){
- case 'I':
- while (st!=' ') st=getchar();
- scanf("%d",&x); tot+=x; sq=floor(sqrt(tot)); min_tot=sq/2; max_tot=sq*2;
- work1(x);
- balance();
- scanf("\n");
- break;
- case 'M':
- while (st!=' ') st=getchar();
- scanf("%d\n",&now);
- break;
- case 'D':
- while (st!=' ') st=getchar();
- scanf("%d\n",&x); work2(x);
- tot-=x; balance();
- break;
- case 'G':
- while (st!=' ') st=getchar();
- scanf("%d\n",&x); work3(x); printf("\n");
- break;
- case 'P':
- now--;st=getchar();st=getchar();st=getchar();
- break;
- case 'N':
- now++;st=getchar();st=getchar();st=getchar();
- break;
- }
- }
- return 0;
- }
分块真心强大,,,
【BZOJ 1507】【NOI 2003】&【Tyvj P2388】Editor 块状链表模板题的更多相关文章
- 【BZOJ-1507】Editor 块状链表
1507: [NOI2003]Editor Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 3397 Solved: 1360[Submit][Stat ...
- BZOJ 4864: [BeiJing 2017 Wc]神秘物质 (块状链表/平衡树 )
这就是一道数据结构裸题啊,最大极差就是区间最大值减最小值,最小极差就是相邻两个数差的最小值.然后平衡树splay/treap或者块状链表维护就行了. 第一次自己写块状链表,蛮好写,就是长..然后就BZ ...
- 【块状链表】AutSky_JadeK的块状链表模板+总结(STL版)
Part 1.块状链表. 定位 插入 删除 数组 O(1) O(n) O(n) 链表 O(n) O(1) O(1) 对于线性表的以上常见操作来说,数组和链表都无法有效地解决.但是,若我们将链表的每 ...
- bzoj 4622: [NOI 2003] 智破连环阵【dfs+匈牙利算法】
一个炸弹炸一个区间的武器,想到二分图匹配 但是直接dfs断点显然不行,预处理出dis[i]为i到m的至多值来最优性剪枝,并且标记ok[i][j]为炸弹i可以炸到j武器,mx[i][j]为i炸弹从j武器 ...
- BZOJ 1509[NOI 2003]逃学的小孩 树形dp
1509: [NOI2003]逃学的小孩 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 995 Solved: 505[Submit][Status][ ...
- 【BZOJ 3188】【Coci 2011】Upit Splay模板题
转啊转终于转出来了,然而我的模板跟陈竞潇学长的模板一模一样,还是太弱啊,第一次用指针. #include<cstdio> #include<cstring> #include& ...
- BZOJ 1036 树的统计Count 树链剖分模板题
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1036 题目大意: 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将 ...
- [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)
[BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...
- BZOJ 1507 Editor(块状链表)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1507 题意:一个文本编辑器,模拟以下操作: 思路:块状链表的主要操作: (1)find( ...
随机推荐
- SharePoint Error:a system restart from a previous installation or update is pending
run:regedit 打开注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager 删除PendingFileR ...
- OpenCV的安装与系统环境变量
OpenCV的安装与系统环境变量 安装OpenCV本来是很简单的一件事,但配置却很麻烦.而且在配置过程中尤为重要的步骤就是系统环境变量的配置.我使用的是CodeBlick13.12与OpenCV1.0 ...
- POJ 3150 Cellular Automaton --矩阵快速幂及优化
题意:给一个环,环上有n块,每块有个值,每一次操作是对每个点,他的值变为原来与他距离不超过d的位置的和,问k(10^7)次操作后每块的值. 解法:一看就要化为矩阵来做,矩阵很好建立,大白书P157页有 ...
- MySQL数据库学习笔记(三)----基本的SQL语句
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- 第22章 DLL注入和API拦截(2)
22.4 使用远程线程来注入DLL 22.4.1 概述 (1)远程线程注入是指一个进程在另一个进程中创建线程,然后载入我们编写的DLL,并执行该DLL代码的技术.其基本思路是通过CreateRemot ...
- js常用宽高属性
document.body.clientWidth //body对象的宽度 document.body.clientHeight //body对象的高度 document.documentElemen ...
- js中的垃圾回收机制
代码回收规则如下: 1.全局变量不会被回收. 2.局部变量会被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁. 3.只要被另外一个作用域所引用就不会被回收 (闭包)
- Linux Linux程序练习十(网络编程大文件发送)
//网络编程客户端--大文件传输 #include <stdio.h> #include <stdlib.h> #include <string.h> #inclu ...
- ZooKeeper学习第八期——ZooKeeper伸缩性
一.ZooKeeper中Observer 1.1 ZooKeeper角色 经过前面的介绍,我想大家都已经知道了在ZooKeeper集群当中有两种角色Leader和Follower.Leader可以接受 ...
- JAVA中获取当前系统时间
一. 获取当前系统时间和日期并格式化输出: import java.util.Date;import java.text.SimpleDateFormat; public class NowStrin ...