POJ2887 Big String(块状数组)

参考:http://blog.csdn.net/htt_h/article/details/44862813

题意:

给你一个不超过1e6的字符串,和不超过2000次的操作

操作分为两种:

1.将一个字符插入到某个位置的前面

2.询问当前位置的字符

思路:

学了一发块状数组,就是把1e6的原串分为1e3份,每份长度相同,

由于操作不超过两千次,那每一份的长度不会超过3e3,

可以开一个1e3*3e3的字符数组来存储串,开一个1e3的长度数组记录每部分的长度

这样就可以在较短的时间内完成插入和查找操作

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int N=1e3+10;
char s[N*N],eg[N][N*3],in[2];
int l[N],n,m,x;
void add(char ch,int x)
{
    int nl=0,pn;
    for(int i=0;i<n;i++)
    {
        if(nl+l[i]>=x){pn=i;break;}
        if(i==n-1) {pn=n-1;break;}
        nl+=l[i];
    }
    int p=min(l[pn],x-nl-1);
    for(int i=l[pn];i>p;i--) eg[pn][i]=eg[pn][i-1];
    eg[pn][p]=ch;
    l[pn]++;
}
char query(int x)
{
    int nl=0;
    for(int i=0;i<n;i++)
    {
        if(nl+l[i]>=x) return eg[i][x-nl-1];
        nl+=l[i];
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%s",s))
    {
        int len=strlen(s);
        int ave=(len+999)/1000;
        n=(len-1)/ave+1;
        for(int i=0;i<n;i++) l[i]=ave;
        for(int i=0;i<len;i++) eg[i/ave][i%ave]=s[i];
        l[n-1]=(len-1)%ave+1;
        scanf("%d",&m);
        while(m--)
        {
            scanf("%s",in);
            if(in[0]==‘Q‘)
            {
                scanf("%d",&x);
                printf("%c\n",query(x));
            }
            else
            {
                scanf("%s%d",in,&x);
                add(in[0],x);
            }
        }
    }
    return 0;
}
时间: 2024-10-23 20:19:35

POJ2887 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 (块状数组)

题意:给一个字符串(<=1000000)和n个操作(<2000),每个操作可以在某个位置插入一个字符,或者查询该位置的字符.问查询结果. 思路:块状数组. 如果将原来的字符串都存在一起,每次插入肯定会超时. 而操作数比较少,考虑使用分块法.假设原字符串长度为L,则取每块长度l=sqrt(L).这样每次插入,我们需要用sqrt(L)的时间找到对应的块,再用sqrt(L)在该块进行插入.查询同样需要sqrt(L)找到该块,如果用数组实现可以O(1)找到目标元素.(我尝试用stl链表来做,结果超时了

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

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

题目链接:hdu 5030 Rabbit's String 题目大意:给定k和一个字符串,要求将字符串拆分成k个子串.然后将每个子串中字典序最大的子串选出来,组成一个包含k个字符串的集合,要求这个集合中字典序最大的字符串字典序最小. 解题思路:网赛的时候试图搞了一下这道题,不过水平还是有限啊,后缀数组也是初学,只会切一些水题.赛后看了一下别人的题解,把这题补上了. 首先对整个字符串做后缀数组,除了处理出sa,rank,height数组,还要处理处f数组,f[i]表示说以0~sa[i]开头共有多少

块状数组

定义: 块状数组是基于分块思想的数据结构,较基于分治思想的数据结构如线段树.平衡树等效率较低,但通用性更强.在块状数组的基础上加以扩展,就可以得到块状链表. 原理: 普通数组在处理一些区间问题时,复杂度通常会退化至O(n).一个朴素的想法就是将这个数组分为若干个子区间,同时维护这些子区间的统计值,如区间和.区间最值等.对于某个子区间,如果操作区间覆盖子区间,则在整体上进行修改并打标记.如果操作区间部分覆盖子区间,则将该块标记下放,对区间中被覆盖部分的元素进行暴力操作. 设数组长度为n,将其分为s

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

HNOI2010弹飞绵羊(块状数组)

不得不说块状数组好神奇的啊!这道题的标签可是splay的启发是合并(什么高大上的东西),竟然这么轻松的就解决了! var x,y,i,j,tot,n,m,ch:longint; f,k,l,bl,go:array[0..200100] of longint; procedure init; begin readln(n); x:=trunc(sqrt(n));j:=x; for i:=1 to n do begin if j=x then begin j:=1;inc(tot);l[tot]:=

转换实体对象 与string转化数组

/// <summary> /// 转换实体对象 /// </summary> /// <typeparam name="T1">转化的实体</typeparam> /// <typeparam name="T2">转换后的实体</typeparam> /// <param name="t1"></param> /// <param name=&

uva 12003 Array Transformer (块状数组)

大白书上的393页. 一直在原数组上乱搞.其实要用另外一个数组记录块. 原数组是不能变的. 注意好原数组和块数组的关系,细心一点处理边界.还是不难的. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #define maxn 300005 #define SIZE 600 using namespace std; int a[maxn]; int bl