哈理工OJ 1681“回文串”


回文串
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 107(22 users)Total Accepted: 28(13 users)Rating: Special Judge: No
Description
现在我们有一个很长很长的字符串,并且我们将有两种操作。
C i y:将第i个字符变成y
Q i j:检查第i个字符到第j个字符是否为一个回文串
Input
输入的第一行是一个整数T,表示一共有T组测试数据;
对于每组测试数据,第一行包含一个字符串长度不超过1000000。
接下来一行为一个整数N代表操作次数。N不超过1000000
接下来N行包含一种操作。
所有的字母都是小写字母。
Output
对于每种操作,如果相应的字符串为回文串输出"yes",后则输出"no"。
Sample Input
1
aaaaa
4
Q 1 5
C 2 b
Q 1 5
Q 1 3
Sample Output
yes
no
yes
Author

陈禹@HRBUST

先在这对不明真相的分享代码的同学说抱歉,board没看见删除功能,你的代码是对的。。。输入越界太扯了。。。。

题解:

没给T范围,给了操作数,感觉暴力可解,交一发WA了,然后无脑WA,后来看分享才知道,需要带技巧的暴力。Q操作,我们将string 分为两个半,反转其中一个,如果yes,我们记录这个回文串的头和尾。这样下次Q操作时,如果给的区间在之前回文串的内部话,如果是对称的,直接yes。C操作,如果修改的位置在之前回文串的区间,注意将L=R。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
string a,d,f;
char b[2];
int t,q,x,y;
int L,R;
void QAQ()
{
    scanf("%d%d",&x,&y);
    x--,y--;
    if(x>=L&&(x-L)==(R-y)) {printf("yes\n");return ;}
    int tmp=y-x+1;
    if(tmp%2==0)
    {
        d=a.substr(x,tmp/2);
        f=a.substr(x+tmp/2,tmp/2);
    }
    else
    {
        d=a.substr(x,tmp/2);
        f=a.substr(x+tmp/2+1,tmp/2);
    }
        reverse(d.begin(),d.end());
       if(d==f)
       {
    printf("yes\n");
    L=x,R=y;
       }
    else
        printf("no\n");
    return ;
}
void TAT()
{
    scanf("%d%s",&x,b);
    x--;
    a[x]=b[0];
     if(x>=L&&x<=R)
    {
            L=R;
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        cin>>a;
        scanf("%d",&q);
        while(q--)
        {
            scanf("%s",b);
            if(b[0]=='Q')
            QAQ();
            else
            TAT();
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值