URAL - 1989 Subpalindromes

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37129433/article/details/82431215

题 意:给你一个长度为n的字符串,m次操作,palindrome? l,r。表示询问[l,r]是否是回文串,change x ch 把第x个字符转化成ch。
数据范围:
5<=n,m<=1e5
1 <= l<= r <= n
输入样例:

abcda
5
palindrome? 1 5
palindrome? 1 1
change 4 b
palindrome? 1 5
palindrome? 2 4

输出样例:

No
Yes
Yes
Yes

思 路:思路是分析出来的,有些是一眼题,有些是需要分析的。首先看数据范围,1e5,又是两种操作,很容易就应该想到是线段树,又是回文串啥的,回文串不就是最简单的hash。Hash是一种思想,那是一种可以BDRHHash避免冲突非常高的一种写法。直接转化成进制也可以是一种Hash 的思想。

收 获:要去分析题目,hash也转化成了一种思想。Hash 那个seed能奇数最好奇数。(lll¬ω¬)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef unsigned long long ull;
const int maxn = 1e5+5;
ull sum1[maxn<<2],sum2[maxn<<2];
ull f[maxn];
char s[maxn];
int n,m;
void PushUp(int rt){
    sum1[rt] = sum1[rt<<1] + sum1[rt<<1|1];
    sum2[rt] = sum2[rt<<1] + sum2[rt<<1|1];
}
void build(int l,int r,int rt){
    if(l == r){
        sum1[rt] = ull(s[l]-'a'+1)*f[l-1];  //这也是一种很好的思路
        sum2[rt] = ull(s[l]-'a'+1)*f[n-l];
        return ;
    }
    int m = (l+r)/2;
    build(lson);
    build(rson);
    PushUp(rt);
    return;
}
ull query(int L,int R,int flag,int l,int r,int rt){
    if(L<=l && r<=R){
        if(flag == 1) return sum1[rt];
        else return sum2[rt];
    }
    int m = (l+r)/2;
    ull ans = 0;
    if(L<=m) ans+=query(L,R,flag,lson);
    if(R>m ) ans+=query(L,R,flag,rson);
    return ans;
}
void update(int pos,char x,int l,int r,int rt){
    if(l == r){
        sum1[rt] = (x-'a'+1)*f[l-1];
        sum2[rt] = (x-'a'+1)*f[n-l];
        return;
    }
    int m = (l+r)/2;
    if(pos<=m) update(pos,x,lson);
    else update(pos,x,rson);
    PushUp(rt);
}
int main() {
    scanf("%s",s+1);
    scanf("%d",&m);
    int l,r;
    char str[100];
    n = strlen(s+1);
    f[0] = 1;
    for(int i=1;i<=n;i++){
        f[i] = f[i-1]*13131;
    }
    build(1,n,1);
    while(m--){
        scanf("%s",str);
        if(str[0] == 'p'){
            scanf("%d %d",&l,&r);
            ull ans1,ans2;
            ans1 = query(l,r,1,1,n,1);
            ans2 = query(l,r,2,1,n,1);
            int temp1 = l-1;
            int temp2 = n-r;
//            printf("%d %d %llu %llu\n",temp1,temp2,ans1,ans2);
            if(temp1 < temp2){  //这个地方自己去举一个简单的例子就好了。
                ans1 *= f[temp2-temp1];
            }else if(temp1>temp2){
                ans2 *= f[temp1-temp2];
            }

            if(ans1 == ans2){
                printf("Yes\n");
            }else{
                printf("No\n");
            }
        }else{
            char ch[10];
            scanf("%d%s",&l,ch);
            update(l,ch[0],1,n,1);
        }
    }
    return 0;
}
/*
abcba
5
palindrome? 1 3
palindrome? 2 4
palindrome? 3 3

*/

猜你喜欢

转载自blog.csdn.net/qq_37129433/article/details/82431215
今日推荐