/Dãy cấp số cộng

<Problem>

https://oj.vnoi.info/problem/avlbit
              #include <iostream>
        #include <cmath>
        #include <numeric>
        #include <map>
        using namespace std;
        
        using Condition = int (*) (int, int);
        
        #define MAX_SIZE 100010
        
        class SparseTable {
          int table[17][MAX_SIZE];
        
        public:
          void buildTable(int* data, int length, Condition condition) {
            //memcpy(table[0], data, sizeof(table[0]));
            for (int i = 1; i <= length; i++) {
              table[0][i] = data[i];
            }
        
            int lg = log(length) / log(2);
        
            for (int j = 1; j <= lg; j++) {
              for (int i = 1; i <= length - (1 << j) + 1; i++) {
                table[j][i] = condition(table[j - 1][i], table[j - 1][i + (1 << (j - 1))]);
              }
            }
          }
        
          inline int query(int left, int right, Condition condition) {
            int len = right - left + 1;
            int k = log(len) / log(2);
        
            int result = condition(table[k][left], table[k][right - (1 << k) + 1]);
            return result;
          }
        };
        
        int Max(int a, int b);
        int Min(int a, int b);
        int Gcd(int a, int b);
        
        int main() {
          int n, q;
          cin >> n >> q;
        
          int* arr = new int[n + 1];
          for (int i = 1; i <= n; i++) {
            cin >> arr[i];
          }
        
          SparseTable FindMax, FindMin, FindPos, FindGcd;
        
          FindMax.buildTable(arr, n, Max);
          FindMin.buildTable(arr, n, Min);
        
          int* subtract = new int[n];
          for (int i = 1; i <= n - 1; i++) {
            subtract[i] = arr[i + 1] - arr[i];
          }
        
          FindGcd.buildTable(subtract, n - 1, Gcd);
        
          int* appearance = new int[n + 1];
          for (int i = 0; i <= n; i++) appearance[i] = n + 1;
        
          map<int, int> iDex;
        
          for (int i = 1; i <= n; i++) {
            int pos = iDex[arr[i]];
            if (pos > 0) appearance[pos] = i;
            iDex[arr[i]] = i;
          }
        
          FindPos.buildTable(appearance, n, Min);
        
          while (q--) {
            int left, right;
            cin >> left >> right;
        
            int maxInRange = FindMax.query(left, right, Max);
            int minInRange = FindMin.query(left, right, Min);
        
            if (maxInRange == minInRange) {
              cout << "NO" << endl;
            }
            else {
              int len = right - left + 1;
        
              if ((maxInRange - minInRange) % (len - 1) == 0) {
                int dist = (maxInRange - minInRange) / (len - 1);
        
                int pos = FindPos.query(left, right, Min);
                int gcdNum = abs(FindGcd.query(left, right - 1, Gcd));
        
                if (pos > right && gcdNum == dist) {
                  cout << "YES" << endl;
                }
                else {
                  cout << "NO" << endl;
                }
              }
              else {
                cout << "NO" << endl;
              }
            }
          }
        
          return 0;
        }
        
        int Max(int a, int b) {
          return (a >= b) ? a : b;
        }
        int Min(int a, int b) {
          return (a <= b) ? a : b;
        }
        int Gcd(int a, int b) {
          while (b != 0) {
            int r = a % b;
            a = b;
            b = r;
          }
          return a;
        }