<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;
}