*块状链表

今天是2017/5/25,DCDCBigBig的第十二篇博文

哇!这是什么?几百年前写的代码了吧。。。应该是NOI2003文本编辑器那题。。。就先发上来吧。。。

块状链表

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int ML=1024*1024*2+10;
const int BL=20000;
const int MB=ML/BL*2+100;
int list[MB],num[MB],nxt[MB],pos,T,k,now;
char dat[MB][BL],st[11],str[ML],ch;
int newn(){
    return list[pos++];
}
void deln(int n){
    list[--pos]=n;
}
void fid(int &p,int &tmp){
    for(tmp=0;tmp!=-1&&p>num[tmp];tmp=nxt[tmp])p-=num[tmp];
}
void fillb(int tmp,int n,char str[],int nex){
    if(tmp==-1)return;
    nxt[tmp]=nex;
    num[tmp]=n;
    memcpy(dat[tmp],str,n);
}
void spl(int tmp,int p){
    if(tmp==-1||p==num[tmp])return;
    int t=newn();
    fillb(t,num[tmp]-p,dat[tmp]+p,nxt[tmp]);
    nxt[tmp]=t;
    num[tmp]=p;
}
void marge(int tmp){
    for(;tmp!=-1;tmp=nxt[tmp]){
        for(int t=nxt[tmp];t!=-1&&num[tmp]+num[t]<=BL;t=nxt[tmp]){
            memcpy(dat[tmp]+num[tmp],dat[t],num[t]);
            num[tmp]+=num[t];
            nxt[tmp]=nxt[t];
            deln(t);
        }
    }
}
void ins(int p,int n,char str[]){
    int tmp,t,i;
    fid(p,tmp);
    spl(tmp,p);
    for(i=0;i+BL<=n;i+=BL){
        t=newn();
        fillb(t,BL,str+i,nxt[tmp]);
        nxt[tmp]=t;
        tmp=t;
    }
    if(n-i){
        t=newn();
        fillb(t,n-i,str+i,nxt[tmp]);
        nxt[tmp]=t;
    }
    marge(tmp);
}
void ers(int p,int n){
    int tmp,e;
    fid(p,tmp);
    spl(tmp,p);
    for(e=nxt[tmp];e!=-1&&n>num[e];e=nxt[e])n-=num[e];
    spl(e,n);
    for(int t=nxt[tmp];t!=e;t=nxt[tmp]){
        nxt[tmp]=nxt[t];
        deln(t);
    }
    marge(tmp);
}
void get(int p,int n,char str[]){
    int tmp,t,i;
    fid(p,tmp);
    i=min(n,num[tmp]-p);
    memcpy(str,dat[tmp]+p,i);
    for(t=nxt[tmp];t!=-1&&i+num[t]<=n;i+=num[t],t=nxt[t]){
        memcpy(str+i,dat[t],num[t]);
    }
    if(n-i&&t!=-1){
        memcpy(str+i,dat[t],n-i);
    }
    str[n]='\0';
}
int main(){
    scanf("%d",&T);
    for(int i=1;i<=MB;i++){
        list[i]=i;
    }
    pos=0;
    nxt[0]=-1;
    num[0]=0;
    now=0;
    while(T--){
        scanf("%s",st);
        if(st[0]=='M'){
            scanf("%d",&k);
            now=k;
        }
        if(st[0]=='I'){
            scanf("%d",&k);
            for(int i=0;i<k;i++){
                scanf("%c",&ch);
                str[i]=ch;
                if(ch<32||ch>126)i--;
            }
            ins(now,k,str);
        }
        if(st[0]=='D'){
            scanf("%d",&k);
            ers(now,k);
        }
        if(st[0]=='G'){
            scanf("%d",&k);
            get(now,k,str);
            printf("%s\n",str);
        }
        if(st[0]=='P')now--;
        if(st[0]=='N')now++;
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值