POJ 2887 Big String (块状数组)

题意:给一个字符串(<=1000000)和n个操作(<2000),每个操作可以在某个位置插入一个字符,或者查询该位置的字符。问查询结果。

思路:块状数组。

如果将原来的字符串都存在一起,每次插入肯定会超时。

而操作数比较少,考虑使用分块法。假设原字符串长度为L,则取每块长度l=sqrt(L)。这样每次插入,我们需要用sqrt(L)的时间找到对应的块,再用sqrt(L)在该块进行插入。查询同样需要sqrt(L)找到该块,如果用数组实现可以O(1)找到目标元素。(我尝试用stl链表来做,结果超时了)

这样最坏的情况下,一个块最多有2000个字符,当然操作不会超时,但是数组要开得足够大。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <list>
#define ll long long
using namespace std;
int Maxn, N ;
int sum[1005];
struct BlockList
{
    int size;
    char dat[2005];
    int at(int pos)
    {
        return dat[pos];
    }
    void insert(int pos,char c)
    {
        for(int i=++size; i>pos; --i) dat[i]=dat[i-1];
        dat[pos]=c;
    }
    void push_back(char c)
    {
        dat[++size]=c;
    }
};
BlockList block[1005];
char query(int s,int p)
{
    return block[s].at(p);
}
void insert(int s,int p,char c)
{
    p=min(p,block[s].size+1);
    block[s].insert(p,c);
}
void maintain()
{
    for(int i=1; i<=Maxn; ++i)
        sum[i]=sum[i-1]+block[i].size;
}
void MyInsert(int pos,char c)
{
    int p=lower_bound(sum+1,sum+1+Maxn,pos)-(sum);
    insert(p,pos-sum[p-1],c);
    maintain();
}
int MyQuery(int pos)
{
    int p=lower_bound(sum+1,sum+1+Maxn,pos)-(sum);
    return query(p,pos-sum[p-1]);
}
char str[1000005];
void init()
{
    int len=strlen(str)+N;
    Maxn=sqrt(len*1.0)+1;
    for(int i=0; str[i]; ++i)
        block[i/Maxn+1].push_back(str[i]);
    maintain();
}
int main()
{
    gets(str);
    int pos;
    char p[3],s[3];
    scanf("%d",&N);
    init();
    while(N--)
    {
        scanf("%s",p);
        if(p[0]==‘I‘)
        {
            scanf("%s%d",s,&pos);
            MyInsert(pos,s[0]);
        }
        else
        {
            scanf("%d",&pos);
            printf("%c\n",MyQuery(pos));
        }
    }
    return 0;
}

POJ 2887 Big String (块状数组)

时间: 2024-12-30 12:07:31

POJ 2887 Big String (块状数组)的相关文章

Big String 块状数组(或者说平方分割)

Big String 给一个字符串,长度不超过 106,有两种操作: 1. 在第 i 个字符的前面添加一个字符 ch 2. 查询第 k 个位置是什么字符 操作的总数不超过 2000 如果直接模拟的话,移动到后面的数据量太大.我们分块的话,就可以优化,减少移动的量.  很典型的块状数组.块状数组的next指向的是一块,而不是一个.这里用整数代替了指针. 每一个块就是一个对象.这题用面向对象编程. 1 #include <iostream> 2 #include <cstdio> 3

poj 2887 Big String

题目连接 http://poj.org/problem?id=2887 Big String Description You are given a string and supposed to do some string manipulations. Input The first line of the input contains the initial string. You can assume that it is non-empty and its length does not

POJ 2406 Power String 后缀数组

这题曾经用KMP做过,用KMP 做非常的简单,h函数自带的找循环节功能. 用后缀数组的话,首先枚举循环节长度k,然后比较LCP(suffix(k + 1), suffix(0)) 是否等于len - k, 如果相等显然k就是一个循环节. 得到LCP的话可以通过预处理出所有点和0的lcp就好了.另外倍增法构造后缀数组还有用RMQ来搞lcp nlogn是不行的,会超时,所以可以dc3走起了.. #include <cstdio> #include <cstring> #include

POJ 2887 Big String 线段树 离线处理

一开始看的时候没什么思路,后来一看卧槽不是简单的离线处理么.反着插入一遍然后直接查询就好了. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r const int maxq = 2e3 + 10; const

POJ 3729 Facer’s string (后缀数组)

题目大意: 串1中有多少个后缀和 串2中的某个后缀 的lcp 为 k 思路分析: 先找出 长度至少为k的对数有多少. 再找出 至少为k+1的有多少 然后相减. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <map> #include <string> #define maxn 110005 using na

POJ2887 Big String(块状数组)

参考:http://blog.csdn.net/htt_h/article/details/44862813 题意: 给你一个不超过1e6的字符串,和不超过2000次的操作 操作分为两种: 1.将一个字符插入到某个位置的前面 2.询问当前位置的字符 思路: 学了一发块状数组,就是把1e6的原串分为1e3份,每份长度相同, 由于操作不超过两千次,那每一份的长度不会超过3e3, 可以开一个1e3*3e3的字符数组来存储串,开一个1e3的长度数组记录每部分的长度 这样就可以在较短的时间内完成插入和查找

POJ 3294 Life Forms (后缀数组)

题目大意: 求出在m个串中出现过大于m/2次的子串. 思路分析: 如果你只是直接跑一次后缀数组,然后二分答案扫描的话. 那么就试一下下面这个数据. 2 abcdabcdefgh efgh 这个数据应该输出 efgh 问题就在于对于每一个串,都只能参与一次计数,所以在check的时候加一个标记数组是正解. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring>

poj 1159 Palindrome lcs+滚动数组

点击打开链接题目链接 Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 52910   Accepted: 18248 Description A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are

hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分)

Rabbit's String Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 288    Accepted Submission(s): 108 Problem Description Long long ago, there lived a lot of rabbits in the forest. One day, the