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 块状数组(或者说平方分割)的更多相关文章
- Poj 2887 Big String(块状数组)
Big String Time Limit: 1000MS Memory Limit: 131072K Description You are given a string and supposed ...
- POJ 2887 Big String (块状数组)
题意:给一个字符串(<=1000000)和n个操作(<2000),每个操作可以在某个位置插入一个字符,或者查询该位置的字符.问查询结果. 思路:块状数组. 如果将原来的字符串都存在一起,每 ...
- ZOJ2112 Dynamic Rankings 动态区间第K最值 平方分割
有了上一题的经验(POJ的静态区间第K最值)再解决这道题就轻松多了 空间5256KB,时间3330ms,如果把动态开点的平衡树换成数组模拟的话应该会更快 之所以选择了平方分割而不是树套树,不仅是所谓趁 ...
- POJ2104 K-th Number 静态区间第k最值 平方分割
干掉这道题的那一刻,我只想说:我终于**的AC了!!! 最终内存1344K,耗时10282ms,比起归并树.划分树以及其他各种黑科技,这个成绩并不算光彩⊙﹏⊙ 但至少,从最初的无数次TLE到最终的AC ...
- 平方分割poj2104K-th Number
K-th Number Time Limit: 20000MS Memory Limit: 65536K Total Submissions: 59798 Accepted: 20879 Ca ...
- hdu 3553 Just a String (后缀数组)
hdu 3553 Just a String (后缀数组) 题意:很简单,问一个字符串的第k大的子串是谁. 解题思路:后缀数组.先预处理一遍,把能算的都算出来.将后缀按sa排序,假如我们知道答案在那个 ...
- codefroce D. Powerful array[初识块状数组]
codefroce D. Powerful array[初识块状数组] 由于是初始所以,仅仅能先用别人的分析.囧... 题目: 给定一个数列:A1, A2,--,An,定义Ks为区间(l,r)中s出现 ...
- 有序数组每个数平方后,不同数字的个数?O(n)
此乃一道笔试题,当时的确也做出来啦.(但是在细节上还是出错啦,对多次重复出现的数字可能会重复计数,没有记录上次删除的元素) 如题,有序数组,可以知道平方之后在两边的数据较大,中间的数据较小. 因此可以 ...
- POJ2104 (平方分割)二分查找理解。
题意:任意区间求第k大数 思路: 预处理:利用平方分割(分桶法)把区间切割成B = sqrt(n)大小的一块块,然后每个各自排序. 二分第k大数x,接着就需要求[l,r]区间中x的排名,与k比较,将两 ...
随机推荐
- First & First
First有记录则返回,否则返回null FirstOrDefault有记录则返回,否则NEW一个新的实体对象返回
- Cisco 防止SYN Flood 攻击原理
DoS(Denial of Service拒绝服务)和DDoS(Distributed Denial of Service分布式拒绝服务)攻击是大型网站和网络服务器的安全威胁之一.2000年2月,Ya ...
- MFC消息响应机制 q
MFC消息响应机制分析 1 引言微软公司提供的MFC基本类库(Microsoft Foundation Classes),是进行可视化编程时使用最为流行的一个类 库.MFC封装了大部分Windows ...
- IP地址转换成Long型数字的算法
在应用程序开发中,涉及到IP地址的存储,大部分开发人员都将其存为String(或文本类型).能否将固定格式为m.n.x.y的IP地址转换成 Long型的数字呢?答案是肯定的.在数据库层面,可以直接将结 ...
- poj1061 青蛙的约会 扩展欧几里德的应用
这个题解得改一下,开始接触数论,这道题目一开始是看了别人的思路做的,后来我又继续以这种方法去做题,发现很困难,学长告诉我先看书,把各种词的定义看懂了,再好好学习,我做了几道朴素的欧几里德,尽管是小学生 ...
- 粗解Xcode 5新特性: Asset Catalogs
原文:http://schlu.org/2013/10/01/Xcode-Asset-Catalogs.html 基础知识 在今年的WWDC大会上苹果介绍了Asset Catalogs.Asset C ...
- maven 配置文件详解
<projectxmlns="http://maven.apache.org/POM/4.0.0 " xmlns:xsi="http://www.w3.org/20 ...
- [转]Kerberos简介
Kerberos协议: Kerberos协议主要用于计算机网络的身份鉴别(Authentication), 其特点是用户只需输入一次身份验证信息就可以凭借此验证获得的票据(ticket-grantin ...
- Combox和DropDownList控件的区别
共同点:都是下拉框控件 不同点:Combox用在winform上,DropDownList用在网页上,且两者绑定方式略有不同 绑定数据例子如下—— 1.Combox绑定 DataTable dtBus ...
- 函数 MultiByteToWideChar() 详解
函数原型: int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cchMultiByte ...