Advertisement
siiena

rangehd

Feb 20th, 2020
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.44 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. unsigned int t[1000001] = {0};
  6. char a[1000001];
  7.  
  8. int minn(int a, int b) {
  9.     if (a <= b) {
  10.         return a;
  11.     }
  12.     else {
  13.         return b;
  14.     }
  15. }
  16.  
  17. unsigned int query(unsigned int t[], int i) {
  18.     unsigned int v = 0;
  19.     while (i >= 0) {
  20.         v ^= t[i];
  21.         i = (i & (i + 1)) - 1;
  22.     }
  23.     return v;
  24. }
  25.  
  26. unsigned int sdv(unsigned int i) {
  27.         if (i != 0) {
  28.                 return ((i & 1) + sdv(i >> 1));
  29.         }
  30.         else return 0;
  31. }
  32.  
  33. void hd_query(unsigned int t[], int l, int r) {
  34.     unsigned int v = sdv(query(t, r) ^ query(t, l - 1));
  35.         if (v == ((r - l + 1) % 2)) printf("YES\n");
  36.         else printf("NO\n");
  37. }
  38.  
  39. void update(unsigned int t[], int i, unsigned int q, int n) {
  40.     while (i < n) {
  41.         t[i] ^= q;
  42.         i = (i | (i + 1));
  43.     }
  44. }
  45.  
  46. int build(char a[], int n, int l, int r, unsigned int t[]) {
  47.     unsigned int sum = 0, bound = minn(r, n);
  48.     while (l < bound) {
  49.         int m = (l + r) / 2;
  50.         sum ^= build(a, n, l, m, t);
  51.         l = m + 1;
  52.         }
  53.         if (r < n) {
  54.                 sum ^= (1 << (a[r] - 'a'));
  55.                 t[r] = sum;
  56.         }
  57.     return sum;
  58. }
  59.  
  60. void ftree_build(char a[], int n) {
  61.     unsigned int w = 2;
  62.     while (w <= n) w *= 2;
  63.     unsigned int r = w;
  64.     build(a, n, 0, r - 1, t);
  65. }
  66.  
  67. void update1(unsigned int t[], char a[], int l, char rr[], int n, int nr) {
  68.         int i = 0;
  69.         while (i < nr) {
  70.                 if (rr[i] - a[l + i]) {
  71.                         update(t, l + i, ((1 << (rr[i] - 'a')) + (1 << (a[l + i] - 'a'))), n);
  72.                 }
  73.                 a[l + i] = rr[i];
  74.                 i++;
  75.         }
  76. }
  77.  
  78. int main() {
  79.     int n, k, l, r;
  80.     scanf("%s", a);
  81.         n = strlen(a);
  82.         scanf("%d", &k);
  83.         ftree_build(a, n);
  84.     char str[3], hdd[] = "HD", rr[1000001];
  85.     for (int i = 0; i < k; i++) {
  86.             scanf("%s", &str);
  87.             if ((int)strcmp(str, hdd) == 0) {
  88.                         scanf("%d %d", &l, &r);
  89.                         hd_query(t, l, r);
  90.                 }
  91.             else {
  92.                         scanf("%d %s", &l, rr);
  93.                         update1(t, a, l, rr, n, strlen(rr));
  94.                 }
  95.     }
  96. }
  97.  
  98. ____________________________________________________________________________________________________________________________
  99.  
  100. Определение гипердромов в строке
  101.  
  102. Гипердром – это строка, из букв которой можно составить палиндром. Другими словами, любая буква имеет чётное количество вхождений (возможно, нулевое) в гипердром чётной длины. Если же гипердром имеет нечётную длину, то ровно одна буква имеет нечётное количество вхождений.
  103. Составьте программу rangehd.c, определяющую, является ли указанная подстрока строки гипердромом. Строка время от времени может изменяться.
  104.  
  105. Формат входных данных
  106. Первая строчка, считываемая со стандартного потока ввода, содержит строку размера n (0 < n ≤ 1000000). Строка состоит из маленьких латинских букв.
  107. Вторая строчка содержит общее количество выполняемых операций m (0 < m ≤ 10000). Каждая из следующих m строчек содержит описание операции.
  108. Операция либо имеет форму HD l r (определить, является ли подстрока, начинающаяся с индекса l и заканчивающаяся индексом r, гипердромом), либо форму UPD i s (заменить подстроку, начинающуюся с индекса i, строкой s).
  109. Формат результата работы программы
  110. Для каждой операции HD вывести в стандартный поток вывода слово «YES», если подстрока является гипердромом, или слово «NO» в противном случае.
  111. Пример работы программы
  112.  
  113. Ввод:
  114. aababab
  115. 6
  116. HD 0 6
  117. HD 1 6
  118. HD 0 3
  119. UPD 2 qqq
  120. HD 0 6
  121. HD 1 5
  122. Вывод:
  123. YES
  124. NO
  125. NO
  126. NO
  127. YES
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement