Newcoder MIRЯOЯ (线段树)

版权声明:转载请标明出处 https://blog.csdn.net/weixin_41190227/article/details/89500248

链接:https://ac.nowcoder.com/acm/contest/624/E
来源:牛客网
 

As most people don't know, the world has a dark side. Ramen is the peacemaker between the bright world and the dark world. The dark world is the symmetry of the bright world, so to communicate between two worlds, Ramen uses a magic mirror.

We can describe the events that have happened using an event sequence. For example, a sequence of rsw may represent the events: rainy, sunny, windy. As the symmetry of the bright world, the event sequence of the dark side should be wsr, i.e., the reversal of the bright one. Ramen likes to join two event sequences into one, so he can observe the two world conveniently. His event sequence should be rswwsr. The first half and the second half should always be a symmetry to make the two worlds stay in harmony.

These days, a mysterious force is breaking the rules of both worlds. They have the ability that can change the events regardless of the time. If they changed some events in one world, the modifies will not reflect in another world and there will be no harmony. But luckily, Ramen has set up some magic monitors so he can receive the warning in no time. Ramen gives you the list that how the force changes the world and wants you to help him to check that if some event sequences are valid in both worlds so that he can fix the order of the world in time.

输入描述:

The input contains multiple lines.

The first line contains two integers n,m(1 <= n, m <= 1e5), indicates the number of event sequence and the number of operations.

The next line contains a string S, indicates the event sequence. It's guaranteed that S includes only lower case Lattin letters, i.e., a-z.

Each of the next m lines gives an operation. The format of operations are:
- 1 p ch: change the event at position p(1 <= p <= n) into ch.
- 2 l r: query that whether the subsequence [l,r] is centrosymmetric. 1 <= l <= r <= n.

输出描述:

For each query, i.e., the operation 2, output YES if the subsequence is centrosymmetric, otherwise NO.

示例1

输入

复制

6 6
mirror
2 3 3
2 1 6
1 2 o
2 2 3
2 2 4
2 1 6

输出

复制

YES
NO
YES
YES
NO

备注:

A subsequence [l,r] is centrosymmetric if and only if the reversal of subsequence [n-r+1,n-l+1] is identical with the subsequence [l,r].

题目大意:给一个长度为n的字符串,有m次询问,询问方式两种:- 1 p ch: change the event at position p(1 <= p <= n) into ch.意思是把p这个位置的字符改写成ch;- 2 l r: query that whether the subsequence [l,r] is centrosymmetric. 1 <= l <= r <= n.意思是询问l到r的区间的这段子字符串是否是终点对称的。(对称的要求是[n - r + 1, n - l + 1] 与[l, r]是回文串)

解题思路:遍历整个字符串,看前后对应的位置是否是相同的字符,相同则标记为1,否则标记为0。最后利用线段树去为这个数组即可。每次查询的时候看这个区间的和是否和区间长度相同就可以了。

题目链接:https://ac.nowcoder.com/acm/contest/624/E

/*
@Author: Top_Spirit
@Language: C++
*/
#include <bits/stdc++.h>
using namespace std ;
typedef long long ll ;
typedef pair < ll, ll > P ;
const int Maxn = 1e5 + 10 ;
const int INF = 1e18 ;

#define lson ri << 1, l, mid
#define rson ri << 1 | 1, mid + 1, r

struct Node {
    int l, r ;
}a[Maxn << 2];

int pre[Maxn], sum[Maxn << 2] ;
int n, m ;
char s[Maxn] ;

void pushUp(int ri){
    sum[ri] = sum[ri << 1] + sum[ri << 1 | 1] ;
}

void Build (int ri, int l, int r) {
    a[ri].l = l ;
    a[ri].r = r ;
    if (l == r) {
        sum[ri] = pre[l] ;
        return ;
    }
    int mid = (l + r) >> 1 ;
    Build(lson) ;
    Build(rson) ;
    pushUp(ri) ;
}

void Update (int ri, int k, int val){
    if (a[ri].l == k && a[ri].r == k) {
        sum[ri] = val ;
        return ;
    }
    int mid = (a[ri].l + a[ri].r) >> 1 ;
    if (k <= mid) Update(ri << 1, k, val) ;
    else Update(ri << 1 | 1, k, val) ;
    pushUp(ri) ;
}

int query(int ri, int l, int r){
    if (a[ri].l == l && a[ri].r == r){
        return sum[ri] ;
    }
    int mid = (a[ri].l + a[ri].r) >> 1 ;
    if (r <= mid)  return query(ri << 1, l, r) ;
    else if (l > mid) return query(ri << 1 | 1, l, r) ;
    else {
        return query(lson) + query(rson) ;
    }
}

int main (){
    while (cin >> n >> m){
        memset(pre, 0, sizeof(pre)) ;
        memset(a, 0, sizeof(a)) ;
        cin >> s + 1 ;
        for (int i = 1; i <= (n + 1) / 2; i++){
            if (s[i] == s[n - i + 1]) pre[i] = pre[n - i + 1] = 1 ;
            else pre[i] = pre[n - i + 1] = 0 ;
        }
        Build(1, 1, n) ;
        int op ;
        while (m--){
            cin >> op ;
            if (op == 1) {
                int p ;
                char ch[2] ;
                cin >> p >> ch ;
                s[p] = ch[0] ;
                if (s[p] == s[n - p + 1]) pre[p] = pre[n - p + 1] = 1 ;
                else pre[p] = pre[ n - p + 1] = 0 ;
                Update(1, p, pre[p]) ;
                Update(1, n - p + 1, pre[p]) ;
            }
            else {
                int l, r ;
                cin >> l >> r ;
                int ans = query(1, l, r) ;
                if (ans == r - l + 1) cout << "YES" << endl ;
                else cout << "NO" << endl ;
            }
        }
    }
    return 0 ;
}

猜你喜欢

转载自blog.csdn.net/weixin_41190227/article/details/89500248
今日推荐