Big String 

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

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

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

操作的总数不超过 2000

如果直接模拟的话,移动到后面的数据量太大。我们分块的话,就可以优化,减少移动的量。  很典型的块状数组。块状数组的next指向的是一块,而不是一个。这里用整数代替了指针。

每一个块就是一个对象。这题用面向对象编程。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long LL;
const int INF=0x4fffffff;
const int EXP=1e-;
const int MS=; struct node
{
int size,next;
char str[MS];
void push(char ch)
{
str[size++]=ch;
}
void insert(int pos,char ch)
{
for(int i=size++;i>pos;i--)
str[i]=str[i-];
str[pos]=ch;
} }nodes[MS]; char S[*MS];
int SIZE,cnt,Q; void input()
{
scanf("%s",S);
scanf("%d",&Q);
int len=strlen(S);
SIZE=(int)sqrt(0.1+len+Q);
cnt=;
nodes[cnt].size=;
for(int i=;i<len;i++)
{
if(nodes[cnt].size>=SIZE)
{
nodes[cnt].next=cnt+;
nodes[++cnt].size=;
}
nodes[cnt].push(S[i]);
}
nodes[cnt].next=-;
} //设一个块的最大容量为2*SIZE,当满了就要从后面使用一块来补充
void updata(int id)
{
if(nodes[id].size<*SIZE) // 我们是在区间插入一个字符后在更新,所以要留一个位置
return ;
++cnt;
int i,j,k=nodes[id].size;
for(i=SIZE,j=;i<k;i++,j++)
nodes[cnt].str[j]=nodes[id].str[i];
nodes[cnt].size=j;
nodes[id].size=SIZE;
nodes[cnt].next=nodes[id].next;
nodes[id].next=cnt;
} void solve()
{
int i,j,pos;
char cmd[MS];
for(i=;i<Q;i++)
{
scanf("%s",cmd);
if(cmd[]=='Q')
{
scanf("%d",&pos);
for(j=;pos>nodes[j].size;j=nodes[j].next)
pos-=nodes[j].size;
printf("%c\n",nodes[j].str[pos-]);
}
else
{
scanf("%s%d",cmd,&pos);
for(j=;pos>nodes[j].size&&nodes[j].next!=-;j=nodes[j].next)
pos-=nodes[j].size;
nodes[j].insert(min(pos-,nodes[j].size),cmd[]);
updata(j);
}
}
} int main()
{
input();
solve();
return ;
}

   

Big String 块状数组(或者说平方分割)的更多相关文章

  1. Poj 2887 Big String(块状数组)

    Big String Time Limit: 1000MS Memory Limit: 131072K Description You are given a string and supposed ...

  2. POJ 2887 Big String (块状数组)

    题意:给一个字符串(<=1000000)和n个操作(<2000),每个操作可以在某个位置插入一个字符,或者查询该位置的字符.问查询结果. 思路:块状数组. 如果将原来的字符串都存在一起,每 ...

  3. ZOJ2112 Dynamic Rankings 动态区间第K最值 平方分割

    有了上一题的经验(POJ的静态区间第K最值)再解决这道题就轻松多了 空间5256KB,时间3330ms,如果把动态开点的平衡树换成数组模拟的话应该会更快 之所以选择了平方分割而不是树套树,不仅是所谓趁 ...

  4. POJ2104 K-th Number 静态区间第k最值 平方分割

    干掉这道题的那一刻,我只想说:我终于**的AC了!!! 最终内存1344K,耗时10282ms,比起归并树.划分树以及其他各种黑科技,这个成绩并不算光彩⊙﹏⊙ 但至少,从最初的无数次TLE到最终的AC ...

  5. 平方分割poj2104K-th Number

    K-th Number Time Limit: 20000MS   Memory Limit: 65536K Total Submissions: 59798   Accepted: 20879 Ca ...

  6. hdu 3553 Just a String (后缀数组)

    hdu 3553 Just a String (后缀数组) 题意:很简单,问一个字符串的第k大的子串是谁. 解题思路:后缀数组.先预处理一遍,把能算的都算出来.将后缀按sa排序,假如我们知道答案在那个 ...

  7. codefroce D. Powerful array[初识块状数组]

    codefroce D. Powerful array[初识块状数组] 由于是初始所以,仅仅能先用别人的分析.囧... 题目: 给定一个数列:A1, A2,--,An,定义Ks为区间(l,r)中s出现 ...

  8. 有序数组每个数平方后,不同数字的个数?O(n)

    此乃一道笔试题,当时的确也做出来啦.(但是在细节上还是出错啦,对多次重复出现的数字可能会重复计数,没有记录上次删除的元素) 如题,有序数组,可以知道平方之后在两边的数据较大,中间的数据较小. 因此可以 ...

  9. POJ2104 (平方分割)二分查找理解。

    题意:任意区间求第k大数 思路: 预处理:利用平方分割(分桶法)把区间切割成B = sqrt(n)大小的一块块,然后每个各自排序. 二分第k大数x,接着就需要求[l,r]区间中x的排名,与k比较,将两 ...

随机推荐

  1. 第二百零一天 how can I坚持

    sql要学的东西还很多,很简单的一个sql都不会写,还得请教别人,哎. 八千代.铜钱草,小叶元宝,绿萝.还有我的鱼,还有罗娜. 今天试用了一下三星,系统优化就是不行啊,掉电太快,想搞个小米5,还想买个 ...

  2. Linux查找文件夹名

    @(编程) find / -type d -name filename type的类型 -type c File is of type c: b block (buffered) special c ...

  3. centOS安装openoffice

    centOS安装openoffice的方法: yum install openoffice.org-writer yum install openoffice.org-calc yum install ...

  4. 使用VS2013调试FluorineFx程序

    VS2013,建立 FluorineFx Web 项目方法: 先新建.项目.Web.选择.NET 3.5 ASP.NET 窗体程序来新建一个项目.复制 log.Templates.WEB-INF 文件 ...

  5. [转]Kerberos简介

    Kerberos协议: Kerberos协议主要用于计算机网络的身份鉴别(Authentication), 其特点是用户只需输入一次身份验证信息就可以凭借此验证获得的票据(ticket-grantin ...

  6. java 编译带包文件

    问题   假设两个文件:     D:\workspace\com\A.java     D:\workspace\com\B.java 两个文件都有:     package com;   如何编译 ...

  7. 钉钉开发笔记(3)MySQL的配置

    最近在编写web的过程中,经常需要与后台工作人员互动.由于比较麻烦.没有效率. 就果断的请教了,公司的后台大牛,学习下数据库的一些简单操作,现在就把利用MySQL连接服务器, 进行可视化操作的简单步骤 ...

  8. wikioi 1098 均分纸牌

    题目描述 Description 有 N 堆纸牌,编号分别为 1,2,-, N.每堆上有若干张,但纸牌总数必为 N 的倍数.可以在任一堆上取若于张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取的纸 ...

  9. 常见的Unix指令

    ls -1 列出当前目录下的所有内容(文件/文件夹) pwd 显示当前操作的目录 cd   改变当前操作的目录 who 显示当前用户 clear 清屏 mkdir 新建一个目录 touch 新建一个文 ...

  10. Simple Worker Thread Class

    http://www.codeproject.com/Articles/36184/Simple-Worker-Thread-Class Introduction Many times we need ...