【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( ...
随机推荐
- [cocos2dx] 让UIButton支持disable状态
摘要: 主要解决cocos2dx-2.2.2版本中, UIButton显示不了disable状态图的问题. 顺便, 理解了一下cocos2dx中UIWidget的渲染原理. 博客: http://ww ...
- UESTC 913 握手 Havel定理+优先队列
给定一个非负整数序列{dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化.进一步,若图为简单图,则称此序列可简单图化. 此题因为是无自环无重边,所以是简单图.用判定简单图可图化 ...
- HDU 5084 HeHe --找规律
题意: 给出矩阵M,求M*M矩阵的r行c列的数,每个查询跟前一个查询的结果有关. 解法: 观察该矩阵得知,令ans = M*M,则 ans[x][y] = (n-1-x行的每个值)*(n-1+y列的每 ...
- ZOJ 3232 It's not Floyd Algorithm --强连通分量+Floyd
题意:给你一个传递闭包的矩阵,mp[u][v] = 1表示u可以到达v,为0代表不可到达,问你至少需要多少条边组成的传递闭包符合这个矩阵给出的关系 分析:考虑一个强连通分量,如果这个分量有n个节点,那 ...
- TestLink学习三:发送邮件的两种配置方法
第一种:修改config.inc.php中的[smtp],配置为默认本地发送,用hotmail用户做接收,调试成功!(本人未尝试这种) // ----------------------------- ...
- java9-5 修饰符
1. 修饰符: 权限修饰符:private,默认的,protected,public 状态修饰符:static,final 抽象修饰符:abstract 类: 权限修饰符:默认修饰符,public 状 ...
- for循环的三种写法
第一种写法 传统的方法,遍历数组 String[] arr = { "amy", "heinrich", "cindy", "g ...
- 关于MySql全文索引
从 Mysql 4.0 开始就支持全文索引功能,但是 Mysql 默认的最小索引长度是 4.如果是英文默认值是比较合理的,但是中文绝大部分词都是2个字符,这就导致小于4个字的词都不能被索引,全文索引功 ...
- SQL2008安装后激活方式以及提示评估期已过解决方法(转)
第一步:进入SQL2008配置工具中的安装中心第二步:再进入维护界面,选择版本升级第三步:进入产品密钥,输入密钥第四步:一直点下一步,直到升级完毕.SQL Server 2008 Developer: ...
- [转]php 解决json_encode中文UNICODE转码问题
FROM : http://blog.csdn.net/bjash/article/details/9834497 用PHP的json_encode来处理中文的时候, 中文都会被编码, 变成不可读的, ...