您的位置:首页 > 其它

poj2887 Big String(块状链表)

2018-01-17 15:39 330 查看
题目链接

分析:

块状链表,据说是一种基本不会考到的数据结构,但是好像是骗分的好方法

我们要怎么快速判断一个元素在链表中的哪个结点呢?

记sum表示结点大小的前缀和

我们用lower_bound查找sum中大于等于pos(查找位置的)

的第一个sum[p]

那么结点p就是pos应该插入到的结点

tip

这道题比较简单

链表的形式不是特别明显

因为一开始我们规定了每一个结点的size上限:sqrt(N)

所以在初始化的时候就划入了不同结点

因为只有单点插入操作,所以就不牵扯到分裂操作

初始字符串的大小:1e6

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>

using namespace std;

const int N=1000010;
char s
;
int n,m,num,pos,sum[2005];
struct node{
int size;    //每个块的大小
char data[2002];
void push(char c)
{
size++;
data[size]=c;
}
void insert(int pos,char c)    //暴力插入
{
for (int i=size+1;i>pos;i--)
data[i]=data[i-1];
data[pos]=c;
size++;
}
char get(int pos)   //数组的提取
{
return data[pos];
}
};
node block[2010];

void Sum()    //链表总长度
{
for (int i=1;i<=num;i++)
sum[i]=sum[i-1]+block[i].size;
}

void init()
{
num=sqrt((double)n+m)+1;    //结点数
for (int i=0;i<n;i++)
block[i/num+1].push(s[i]);
Sum();
}

void add(int pos,char c)
{
int p=lower_bound(sum+1,sum+1+num,pos)-sum;   //在的结点编号
block[p].insert(pos-sum[p-1],c);
Sum();
}

char ask(int pos)
{
int p=lower_bound(sum+1,sum+1+num,pos)-sum;
return block[p].get(pos-sum[p-1]);
}

int main()
{
scanf("%s",s);
n=strlen(s);

scanf("%d",&m);
init();
char opt[10],c[10];
for (int i=1;i<=m;i++)
{
scanf("%s",&opt);
if (opt[0]=='Q')
{
scanf("%d",&pos);
printf("%c\n",ask(pos));
}
else
{
scanf("%s%d",c,&pos);
add(pos,c[0]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: