列表

详情


NC20166. [JSOI2008]火星人PREFIX

描述

火星人最近研究了一种操作:求一个字串两个后缀的公共前缀。比方说,有这样一个字符串:madamimadam, 我们将这个字符串的各个字符予以标号:
序号: 1 2 3 4 5 6 7 8 9 10 11 
字符: m a d a m i m a d a m 
现在, 火星人定义了一个函数LCQ(x, y),表示:该字符串中第x个字符开始的字串,与该字符串中第y个字符开始的字串 ,两个字串的公共前缀的长度。
比方说,LCQ(1, 7) = 5, LCQ(2, 10) = 1, LCQ(4, 7) = 0 
在研究LCQ函数的过程 中,火星人发现了这样的一个关联:如果把该字符串的所有后缀排好序,就可以很快地求出LCQ函数的值;同样, 如果求出了LCQ函数的值,也可以很快地将该字符串的后缀排好序。 
尽管火星人聪明地找到了求取LCQ函数的快速 算法,但不甘心认输的地球人又给火星人出了个难题:
在求取LCQ函数的同时,还可以改变字符串本身。具体地说 ,可以更改字符串中某一个字符的值,也可以在字符串中的某一个位置插入一个字符。
地球人想考验一下,在如此复杂的问题中,火星人是否还能够做到很快地求取LCQ函数的值。

输入描述

第一行给出初始的字符串。
第二行是一个非负整数M,表示操作的个数。接下来的M行,每行描述一个操作。
操作有3种,如下所示
1、询问。语法:Qxy,x,y均为正整数。功能:计算LCQ(x,y)限制:1 ≤ x,y ≤ 当前字符串长度。
2、修改。语法:Rxd,x是正整数,d是字符。功能:将字符串中第x个数修改为字符d。限制:x不超过当前字 符串长度。
3、插入:语法:Ixd,x是非负整数,d是字符。功能:在字符串第x个字符之后插入字符d,如果x=0,则在字 符串开头插入。限制:x不超过当前字符串长度

输出描述

对于输入文件中每一个询问操作,你都应该输出对应的答案。一个答案一行。

示例1

输入:

madamimadam
7
Q 1 7
Q 4 8
Q 10 11
R 3 a
Q 1 7
I 10 a
Q 2 11

输出:

5
1
0
2
1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 780ms, 内存消耗: 672K, 提交时间: 2022-04-18 11:22:29

#include<iostream>
using namespace std;
string s;
int query(){
    int num=0;
    int i,j;
    cin>>i>>j;
    int n=s.size();
    while(j<=n){
        if(s[i-1]!=s[j-1])break;
        num++;
        i++;
        j++;
    }
    return num;
}

void change(){
    int index;
    char c;
    cin>>index>>c;
    if(index<=s.size())
    s[index-1]=c;
}

void insert(){
    int index;
    string c;
    cin>>index>>c;
    s.insert(index,c);
}

int main(){
    
    int n;
    cin>>s>>n;
    while(n--){
        char c;
        int b,e;
        cin>>c;
        switch(c){
            case 'Q':cout<<query()<<endl;break;
            case 'R':change();break;
            case 'I':insert();break;
        }
    }
    return 0;
}

上一题