poj 2887 Big String

Big String
Time Limit: 1000MS Memory Limit: 131072K
Total Submissions: 5792 Accepted: 1353

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 exceed 1,000,000.

The second line contains the number of manipulation commands N (0 < N  2,000). The following N lines describe a command each. The commands are in one of the two formats below:

  1. I ch p: Insert a character ch before the p-th character of the current string. If p is larger than the length of the string, the character is appended to the end of the string.
  2. Q p: Query the p-th character of the current string. The input ensures that the p-th character exists.

All characters in the input are digits or lowercase letters of the English alphabet.

Output

For each Q command output one line containing only the single character queried.

Sample Input

ab
7
Q 1
I c 2
I d 4
I e 2
Q 5
I f 1
Q 3

Sample Output

a
d
e

这题是用块链过的,差点被卡时间了,接近700ms。因为我是写的动态分配型的,不会写数组版的。

但这题如果用其他数据结构,貌似会TLE,因为O(nlogn)的建树时间,在n=10^6的情况下,那是伤不起的!

但是说句实话,块链真不适合竞赛写!

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#define Maxn 1000010
using namespace std;

char s[Maxn];
const int max_size=1000;
struct blocklist{
    char num[max_size];
    int sz;
    blocklist* next;
    blocklist():sz(0),next(0){}
}*head=NULL;
blocklist* get_pos(int &x){
    blocklist* ret=head;
    while(ret&&x>ret->sz){
        x-=ret->sz;
        ret=ret->next;
    }
    if(!ret) x=1;
    return ret;
}
bool merge(blocklist* pos){
    if(!pos||!pos->next) return false;
    if(pos->sz+pos->next->sz<=max_size){
        memmove(pos->num+pos->sz,pos->next->num,sizeof(char)*pos->next->sz);
        pos->sz+=pos->next->sz;
        blocklist* u=pos->next;
        pos->next=u->next;
        delete u;
        return true;
    }
    return false;
}
void maintain(){
    blocklist* pos=head;
    while(pos){
        merge(pos);
        pos=pos->next;
    }
}
void split(blocklist* pos,int x){
    blocklist* tmp=pos->next;
    pos->next=new blocklist();
    pos->next->next=tmp;
    memmove(pos->next->num,pos->num+x-1,sizeof(char)*(pos->sz-x+1));
    pos->next->sz=pos->sz-x+1;
    pos->sz=x-1;
}
void insert(int x,int n,char* ch){
    blocklist* pos=get_pos(x);
    if(pos) split(pos,x);
    else{
        pos=new blocklist();
        if(!head) head=pos;
        else{
            blocklist* it;
            for(it=head;it->next;it=it->next);
            it->next=pos;
        }
    }
    for(int i=0;i<n;i++){
        if(pos->sz==max_size){
            blocklist* tmp=pos->next;
            pos->next=new blocklist();
            pos->next->next=tmp;
            pos=pos->next;
        }
        pos->num[pos->sz++]=ch[i];
    }
    maintain();
}
char query(int n){
    blocklist* pos=head;
    while(n>pos->sz){
        n-=pos->sz;
        pos=pos->next;
    }
    return pos->num[n-1];
}
int main()
{
    char ch[10];
    int n,p,x;
    scanf("%s",s);
    int len=strlen(s);
    insert(1,len,s);
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%s",ch);
        if(ch[0]=='Q'){
            scanf("%d",&x);
            printf("%c\n",query(x));
        }
        else{
            scanf("%s%d",ch,&p);
            insert(p,1,ch);
        }
    }
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值