首页 > 代码库 > Subpalindromes

Subpalindromes

题目链接

  • 题意:
    给一个字符串(长度不超过1e5),m次操作(m不超过1e5),每次操作:1、查询[l, r]是否是回文串2、修改p位置的值为v
  • 分析:
    这个题目涉及到回文串的一个处理方式:判断正向和反向是否相同,比较简单的方式是采用Hash判别。之后的问题就是点更新和查询区间,线段树解决
const int MAXN = 410000;

const int SEED = 13331;
ULL f[MAXN];
char ipt[MAXN], t[110];

#define lson rt << 1
#define rson rt << 1 | 1

struct Node
{
    int l, r, m;
    ULL vl, vr;
} nd[MAXN << 2], tt;

void merge(Node& ret, Node& l, Node& r, int L, int M, int R)
{
    ret.vl = r.vl * f[M - L + 1] + l.vl;
    ret.vr = l.vr * f[R - M] + r.vr;
}

void pushup(int rt)
{
    merge(nd[rt], nd[lson], nd[rson], nd[rt].l, nd[rt].m, nd[rt].r);
}

void build(int l, int r, int rt)
{
    nd[rt].l = l; nd[rt].r = r; nd[rt].m = (r + l) >> 1;
    if (l == r)
    {
        nd[rt].vl = nd[rt].vr = ipt[l - 1];
    }
    else
    {
        build(l, nd[rt].m, lson);
        build(nd[rt].m + 1, r, rson);
        pushup(rt);
    }
}

void update(int p, int v, int rt)
{
    if (nd[rt].l == nd[rt].r)
    {
        nd[rt].vl = nd[rt].vr = v;
    }
    else
    {
        if (p <= nd[rt].m)
            update(p, v, lson);
        else
            update(p, v, rson);
        pushup(rt);
    }
}

Node query(int L, int R, int rt)
{
    if (L <= nd[rt].l && nd[rt].r <= R)
        return nd[rt];
    if (R <= nd[rt].m)
        return query(L, R, lson);
    else if (L > nd[rt].m)
        return query(L, R, rson);
    Node tl = query(L, R, lson);
    Node tr = query(L, R, rson);
    Node ret;
    merge(ret, tl, tr, max(L, nd[rt].l), nd[rt].m, min(R, nd[rt].r));
    return ret;
}

int main()
{
    f[0] = 1;
    FF(i, 1, MAXN)
        f[i] = f[i - 1] * SEED;
    int n;
    while (~RS(ipt))
    {
        build(1, strlen(ipt), 1);
        RI(n);
        REP(i, n)
        {
            RS(t);
            if (t[0] == 'p')
            {
                int a, b;
                RII(a, b);
                tt = query(a, b, 1);
                printf("%s\n", tt.vl == tt.vr ? "Yes" : "No");
            }
            else
            {
                int p; char v;
                scanf("%d %c", &p, &v);
                update(p, v, 1);
            }
        }
    }
    return 0;
}