QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#268760#4940. Token DistancebruhCompile Error//C++204.1kb2023-11-28 20:45:062023-11-28 20:45:06

Judging History

你现在查看的是最新测评结果

  • [2023-11-28 20:45:06]
  • 评测
  • [2023-11-28 20:45:06]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

template <int (*Merge)(int, int), int Identity>
class SegTree {
 public:
  void Build(const vector<int>& v) {
    N = v.size();
    tree.resize(8 * N);
    Build(0, 0, N - 1, v);
  }

  void Update(int pos, int val) {
    Update(0, 0, N - 1, pos, val);
  }

  int Query(int x, int y) {
    return Query(0, 0, N - 1, x, y);
  }

 private:
  void Build(int ix, int L, int R, const vector<int>& v) {
    if (L == R) {
      tree[ix] = v[L];
      return;
    }
    int M = (L + R) >> 1;
    Build(ix * 2 + 1, L, M, v);
    Build(ix * 2 + 2, M + 1, R, v);
    tree[ix] = Merge(tree[ix * 2 + 1], tree[ix * 2 + 2]);
  }

  void Update(int ix, int L, int R, int pos, int val) {
    if (L == R) {
      tree[ix] = val;
      return;
    }
    int M = (L + R) >> 1;
    if (pos <= M) {
      Update(ix * 2 + 1, L, M, pos, val);
    } else {
      Update(ix * 2 + 2, M + 1, R, pos, val);
    }
    tree[ix] = Merge(tree[ix * 2 + 1], tree[ix * 2 + 2]);
  }

  int Query(int ix, int L, int R, int x, int y) {
    if (x <= L && R <= y) {
      return tree[ix];
    }
    if (R < x || y < L) {
      return Identity;
    }
    int M = (L + R) >> 1;
    return Merge(Query(ix * 2 + 1, L, M, x, y),
                 Query(ix * 2 + 2, M + 1, R, x, y));
  }

  vector<int> tree;
  int N;
};

int Min(int a, int b) {
  return min(a, b);
}

int Max(int a, int b) {
  return max(a, b);
}

int Gcd(int a, int b) {
  return (a == 0 && b == 0) ? 0 : __gcd(a, b);
}

typedef SegTree<Min, INT_MAX> MinSegTree;
typedef SegTree<Max, INT_MIN> MaxSegTree;
typedef SegTree<Gcd, 0> GcdSegTree;

const string kYes = "YES";
const string kNo = "NO";

int main() {
  int N, Q;
  scanf("%d %d", &N, &Q);
  
  vector<int> T(N);
  vector<int> D(N - 1);
  vector<int> leftEqual(N);
  map<int, set<int>> position;

  for (int i = 0; i < N; ++i) {
    scanf("%d", &T[i]);
    if (i > 0) {
      D[i - 1] = abs(T[i] - T[i - 1]);
    }
    if (position.count(T[i]) == 0 || position[T[i]].empty()) {
      leftEqual[i] = INT_MIN;
    } else {
      leftEqual[i] = *(position[T[i]].rbegin());
    }
    position[T[i]].insert(i);
  }

  MinSegTree minT;
  MaxSegTree maxT, maxLeftEqual;
  GcdSegTree gcdD;

  minT.Build(T);
  maxT.Build(T);
  maxLeftEqual.Build(leftEqual);
  gcdD.Build(D);

  while (Q--) {
    int op;
    scanf("%d", &op);
    if (op == 1) {
      int X, Y;
      scanf("%d %d", &X, &Y);
      --X;

      {
        set<int>& oldPos = position[T[X]];
        set<int>::iterator it = oldPos.upper_bound(X);
        if (it != oldPos.end()) {
          int toChange = *it;
          --it;
          leftEqual[toChange] = it == oldPos.begin() ? INT_MIN : *prev(it);
          maxLeftEqual.Update(toChange, leftEqual[toChange]);
        }
        oldPos.erase(X);
      }

      T[X] = Y;
      minT.Update(X, T[X]);
      maxT.Update(X, T[X]);

      {
        set<int>& newPos = position[T[X]];
        set<int>::iterator it = newPos.upper_bound(X);
        if (it != newPos.end()) {
          int toChange = *it;
          leftEqual[toChange] = X;
          maxLeftEqual.Update(toChange, leftEqual[toChange]);  
        }
        leftEqual[X] = it == newPos.begin() ? INT_MIN : *prev(it);
        maxLeftEqual.Update(X, leftEqual[X]);
        newPos.insert(X);
      }
      
      if (X > 0) {
        D[X - 1] = abs(T[X] - T[X - 1]);
        gcdD.Update(X - 1, D[X - 1]);
      }
      if (X + 1 < N) {
        D[X] = abs(T[X + 1] - T[X]);
        gcdD.Update(X, D[X]);
      }
    } else {
      int L, R;
      scanf("%d %d", &L, &R);
      --L; --R;
      
      int delta = maxT.Query(L, R) - minT.Query(L, R);
      int cnt = R - L;
      if (delta == 0) {
        printf("%s\n", kYes.c_str());
      } else if (delta % cnt != 0) {
        printf("%s\n", kNo.c_str());
      } else if (maxLeftEqual.Query(L, R) >= L) {
        printf("%s\n", kNo.c_str());
      } else if (gcdD.Query(L, R - 1) == (delta / cnt)) {
        printf("%s\n", kYes.c_str());
      } else {
        printf("%s\n", kNo.c_str());
     
    }
  }
}

Details

answer.code: In function ‘int main()’:
answer.code:178:2: error: expected ‘}’ at end of input
  178 | }
      |  ^
answer.code:82:12: note: to match this ‘{’
   82 | int main() {
      |            ^
answer.code:84:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   84 |   scanf("%d %d", &N, &Q);
      |   ~~~~~^~~~~~~~~~~~~~~~~
answer.code:92:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   92 |     scanf("%d", &T[i]);
      |     ~~~~~^~~~~~~~~~~~~
answer.code:115:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  115 |     scanf("%d", &op);
      |     ~~~~~^~~~~~~~~~~
answer.code:118:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  118 |       scanf("%d %d", &X, &Y);
      |       ~~~~~^~~~~~~~~~~~~~~~~
answer.code:160:12: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
  160 |       scanf("%d %d", &L, &R);
      |       ~~~~~^~~~~~~~~~~~~~~~~