N - Subpalindromes URAL - 1989 + Hash segment tree

N - Subpalindromes

 URAL - 1989 

This is a hash + tree line, this topic is also not particularly difficult, but it is also more interesting.

The subject gives you two operations, one is answered l ~ r palindrome is not segment, a point is a modified single point.

This is quite easy to use a hash, first of all is to put all the characters mapped to a number, and then give you the equivalent of a string of numbers above operations.

The best idea is to be a small incremental reach hash, this look at the code it, that is not clear.

Note that the main point is to ensure that the last digit of this hash is the same, specifically to see the code.

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
intconst  maxn = 1e5 + 10;
const ull base = 13331;
ull h[maxn], p[maxn];
ull sum1[maxn * 8], sum2[maxn * 8];
int n, m;
char str1[maxn], str2[maxn];

void push_up(int id) {
    sum1[id] = sum1[id << 1] + sum1[id << 1 | 1];
    sum2[id] = sum2[id << 1] + sum2[id << 1 | 1];
    //the printf ( "SUM [% D] =% LLU nisum [% D] =% LLU \ n-", ID, SUM [ID], ID, nisum [ID]); 
} 

void Build ( int ID, int L, int R & lt ) {
     IF (L == R & lt) { 
        SUM1 [ID] = (str1 [L] - ' A ' + . 1 ) * P [L]; // hash assignment, from small to large, incremental assignment 
        sum2 [id] = (str2 [L] - ' A ' + . 1 ) * P [L];
         return ; 
    } 
    int MID = (L + R & lt) >> . 1 ; 
    Build (ID << . 1  , L, MID);
    Build (ID<< 1 | 1, mid + 1, r);
    push_up(id);
}

void update(int id, int l, int r, int pos, int val, int f) {
    if (l == r) {
        if (f == 1) sum1[id] = val * p[l];
        else sum2[id] = val * p[l];
        return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid) update(id << 1, l, mid, pos, val, f);
    else update(id << 1 | 1, mid + 1, r, pos, val, f);
    push_up(id);
}

ull query(int id, int l, int r, int x, int y, int f) {
    if (x <= l && y >= r) {
        if (f == 1) return sum1[id];
        return sum2[id];
    }
    int mid = (l + r) >> 1;
    ull ans = 0;
    if (x <= mid) ans += query(id << 1, l, mid, x, y, f);
    if (y > mid) ans += query(id << 1 | 1, mid + 1, r, x, y, f);
    return ans;
}

char s[maxn], ch[10];


int main() {
    scanf("%s", str1 + 1);
    n = strlen(str1 + 1);
    p[0] = 1;
    for (int i = 1; i <= n; i++) p[i] = p[i - 1] * base, str2[i] = str1[n + 1 - i];
    build(1, 1, n);
    scanf("%d", &m);
    while (m--) {
        int x, y;
        scanf("%s", s);
        if (s[0] == 'p') {
            scanf("%d%d", &x, &y);
            ull rest1 Query = ( . 1 , . 1, n, x, y,  );1 ); // this sub-queries are somewhat more difficult to think 
            ULL rest2 = Query ( 1 , 1 , n-, + n- 1 - Y, + n- 1 - X, 2 );
             IF (X <+ n- 1 - Y) REST 1 = P * [n-+ . 1 - x - Y]; // this is to ensure that if the number of these stages is the same as the rest, the x-axis can draw a know 
            the else rest2 * = P [x + Y - n-- . 1 ]; 

            IF (REST 1 == rest2) the printf ( " Yes \ n- " );
             the else the printf ( " No \ n- " 
        } 
        the else { 
            Scanf ("%d%s", &x, ch);
            update(1, 1, n, x, ch[0] - 'a' + 1, 1);
            update(1, 1, n, n - x + 1, ch[0] - 'a' + 1, 2);
        }
    }
}
Hash

 

Guess you like

Origin www.cnblogs.com/EchoZQN/p/11284840.html