Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- unsigned int t[1000001] = {0};
- char a[1000001];
- int minn(int a, int b) {
- if (a <= b) {
- return a;
- }
- else {
- return b;
- }
- }
- unsigned int query(unsigned int t[], int i) {
- unsigned int v = 0;
- while (i >= 0) {
- v ^= t[i];
- i = (i & (i + 1)) - 1;
- }
- return v;
- }
- unsigned int sdv(unsigned int i) {
- if (i != 0) {
- return ((i & 1) + sdv(i >> 1));
- }
- else return 0;
- }
- void hd_query(unsigned int t[], int l, int r) {
- unsigned int v = sdv(query(t, r) ^ query(t, l - 1));
- if (v == ((r - l + 1) % 2)) printf("YES\n");
- else printf("NO\n");
- }
- void update(unsigned int t[], int i, unsigned int q, int n) {
- while (i < n) {
- t[i] ^= q;
- i = (i | (i + 1));
- }
- }
- int build(char a[], int n, int l, int r, unsigned int t[]) {
- unsigned int sum = 0, bound = minn(r, n);
- while (l < bound) {
- int m = (l + r) / 2;
- sum ^= build(a, n, l, m, t);
- l = m + 1;
- }
- if (r < n) {
- sum ^= (1 << (a[r] - 'a'));
- t[r] = sum;
- }
- return sum;
- }
- void ftree_build(char a[], int n) {
- unsigned int w = 2;
- while (w <= n) w *= 2;
- unsigned int r = w;
- build(a, n, 0, r - 1, t);
- }
- void update1(unsigned int t[], char a[], int l, char rr[], int n, int nr) {
- int i = 0;
- while (i < nr) {
- if (rr[i] - a[l + i]) {
- update(t, l + i, ((1 << (rr[i] - 'a')) + (1 << (a[l + i] - 'a'))), n);
- }
- a[l + i] = rr[i];
- i++;
- }
- }
- int main() {
- int n, k, l, r;
- scanf("%s", a);
- n = strlen(a);
- scanf("%d", &k);
- ftree_build(a, n);
- char str[3], hdd[] = "HD", rr[1000001];
- for (int i = 0; i < k; i++) {
- scanf("%s", &str);
- if ((int)strcmp(str, hdd) == 0) {
- scanf("%d %d", &l, &r);
- hd_query(t, l, r);
- }
- else {
- scanf("%d %s", &l, rr);
- update1(t, a, l, rr, n, strlen(rr));
- }
- }
- }
- ____________________________________________________________________________________________________________________________
- Определение гипердромов в строке
- Гипердром – это строка, из букв которой можно составить палиндром. Другими словами, любая буква имеет чётное количество вхождений (возможно, нулевое) в гипердром чётной длины. Если же гипердром имеет нечётную длину, то ровно одна буква имеет нечётное количество вхождений.
- Составьте программу rangehd.c, определяющую, является ли указанная подстрока строки гипердромом. Строка время от времени может изменяться.
- Формат входных данных
- Первая строчка, считываемая со стандартного потока ввода, содержит строку размера n (0 < n ≤ 1000000). Строка состоит из маленьких латинских букв.
- Вторая строчка содержит общее количество выполняемых операций m (0 < m ≤ 10000). Каждая из следующих m строчек содержит описание операции.
- Операция либо имеет форму HD l r (определить, является ли подстрока, начинающаяся с индекса l и заканчивающаяся индексом r, гипердромом), либо форму UPD i s (заменить подстроку, начинающуюся с индекса i, строкой s).
- Формат результата работы программы
- Для каждой операции HD вывести в стандартный поток вывода слово «YES», если подстрока является гипердромом, или слово «NO» в противном случае.
- Пример работы программы
- Ввод:
- aababab
- 6
- HD 0 6
- HD 1 6
- HD 0 3
- UPD 2 qqq
- HD 0 6
- HD 1 5
- Вывод:
- YES
- NO
- NO
- NO
- YES
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement