5
19
2016
0

【新姿势】块状链表

先来看一道题~

给一个字符串,长度不超过 106,有两种操作:

  1. 在第 i 个字符的前面添加一个字符 ch

  2. 查询第 k 个位置是什么字符

操作的总数不超过 2000


多种数据结构可解.

而我们选择用数组与链表的结合物求解——

块状链表 登登登登~!

先贴代码(实现并不简洁啊..怎么又开启抄代码模式了呢,sigh)

const int N=2000,M=(int)1e6+10;//每块大小阈值 
struct node{
	char s[N];
	int next,siz;
	void init(){
		mec(s,0);
		next=-1;siz=0;
	}
}List[N];
int head,tot,q;
char str[M],ch[5];
void Split(int id)
{
	List[tot].init();
	for(int i=N/2;i<N;i++){
		List[tot].s[i-N/2]=List[id].s[i];
		List[tot].siz++;
		List[id].s[i]=0;
		List[id].siz--;
	}
	List[tot].next=List[id].next;
	List[id].next=tot++;
}
void init(char *str)
{
	head=tot=0;
	List[tot++].init();
	for(int i=0,cur=head;str[i];cur=List[cur].next){
		for(int j=0;j<N&&str[i];i++,j++){//j<N
			List[cur].s[j]=str[i];
			List[cur].siz++;
		}
		if(str[i]){
			List[tot].init();
			List[cur].next=tot++;
		}
	}
	for(int cur=head;cur!=-1;cur=List[cur].next)
		if(List[cur].siz==N) Split(cur);
}
void Insert(int pos,char val) 
{
	int cur=head;
	while(pos>List[cur].siz && List[cur].next!=-1)
		pos-=List[cur].siz,cur=List[cur].next;
	if(pos>=List[cur].siz) List[cur].s[List[cur].siz]=val;//添加到末尾
	else{//此时,pos是块内的位置 
		for(int i=List[cur].siz;i>pos;i--) List[cur].s[i]=List[cur].s[i-1];
		List[cur].s[pos]=val;//注意下标从0开始 
	}
	List[cur].siz++;
	if(List[cur].siz==N) Split(cur);
}
char Find(int pos)
{
	int cur=head;
	while(pos>List[cur].siz) 
		pos-=List[cur].siz,cur=List[cur].next;//顺次查找即可 
	return List[cur].s[pos-1];
}//每块中元素编号0~siz-1 
int main()
{
//	freopen(".in","r",stdin);
	scanf("%s",str);
	init(str);
	scanf("%d",&q);
	while(q--){
		char opt[5];
		int pos;
		scanf("%s",opt);
		if(opt[0]=='I'){
			scanf("%s%d",ch,&pos);
			Insert(pos-1,ch[0]);
		}
		else{
			scanf("%d",&pos);
			printf("%c\n",Find(pos));
		}
	}
	return 0;
}
Category: 分块 | Tags: 分块 块状链表 学习笔记 | Read Count: 606

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com