N - Subpalindromes
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); } } }