[Tree Array] [P5069] [Ynoi 2015] Even as it gets worse

Keywords: PHP less

Description

Given a se q uence of nonnegative integers with the length of (n)(\\\\\\\\\\\\\\\

One operation is to find the location of the maximum value of the sequence, and if there are multiple maximum values, take the left-most one. Then, the number and the number next to the left and right of the position are all (-1\), if reduced to \(0).

Limitation

\(1~\leq~n,~q~\leq~10^5\)

The sequence range is within (10 ^ 9).

Solution

Writing YnOI for the first time was a terrible experience

The first thing to notice is that if you decide to operate on a location (x), then the location must be operated on (a_x\). The reason is that this position will be reduced by one from left to right every time it is operated, so that this position will never be reduced because of the need to operate left and right, so the only way to make this position become(0) is to operate the position itself. So we find a position to operate it all the way to(0) which is equivalent to the original mode of operation. The problem is then translated into finding the sum of all the numbers that will be manipulated.

The number in the presupposition sequence is different from each other. Considering a monotonically increasing or monotonically decreasing extremely long subsequence in a sequence, the maximum value will be operated on first, and the next maximum value will be reduced to(0) after reducing to\(0) and then the next maximum value will be operated to\(0\), and then the next maximum will be reduced to\(0\) It has been found that the parity of all the positions operated is the same, that is, in this extremely long monotone sequence, all points with the same parity as the maximum position will be operated on. Considering that set is used to maintain all the extreme points in the sequence, the number of operations of the initial sequence can be obtained by combining the prefix of odd subscripts and the prefix of even subscripts with two tree array groups, respectively.

When considering modification, it is only necessary to continue to modify the extreme points of the sequence.

So you have to face this point is the extreme point, not the extreme point. His left is the extreme point, and his right is the extreme point, which is not the extreme point. After the modification, the position of the extreme value remains unchanged. After the modification, a new maximum, a new minimum and so on are added in more than a dozen cases.

It is obviously unreliable to consider discussing each case manually, but it is noted that modifying a certain position will only affect the situation where the position is divided into two extreme points (excluding itself) to the left and right, and that only this position and the left and right positions of the position are three new extreme points that may be added or deleted. Location. The answer of this section can be reconstructed violently. Since only all the extremum points in the section need to be scanned, and the number of extremum points is constant, it can be modified by \(O(log n). This( log) is caused by lower_bound of set.

Explain why it affects the second extreme point of left and right numbers, as follows:

9 2 6 8

The three extreme points are (1,2,4\), where (2) is the minimum and (1,4\) is the maximum. If the position (1) is changed to (1\), then the extreme point becomes (1,4). Thus, the interval of ([2,4]) no longer exists and becomes the interval of ([1,4]\) which needs to be re-counted, affecting the \(1\) to the right \(2\\\\\\\\

Consider what happens if the sequence has the same number:

If the same number is discontinuous, it doesn't matter at all. If continuous, let's assume that the first number of this group is larger than the number on the left, then this number will be operated first when the group is operated on, so the first position of this group should be set to the maximum. If the first number of the group is less than the number on the left, it is not up to this number to determine whether the first number is operated on, and it should not become a minimum.

Consider the last number of this group. If it is larger than the number on the right, then the number on the right will continue to operate after the operation. It should not be the maximum. If it is less than the number on the left, then the left and right sides of the interval will stop when the operation to this position, then this position should become a minimum.

There are some details:

Consider that a minimum value will be manipulated, and if and only if its left and right numbers are not manipulated, then it will not be subtracted and can only be operated by itself. In this case, the distance from it to the maximum point is even.

When scanning interval answers, if the interval has (x) extremum points, only the (x-1) interval answers need to be considered, so only (x-1\) extremum points need to be scanned. However, it should be noted that the discussion of the remaining extreme point should not be omitted.

Code

Reference @FlushHu Immortal code, thank you here.

#include <cstdio>
#include <set>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif

typedef long long int ll;

namespace IPT {
  const int L = 1000000;
  char buf[L], *front=buf, *end=buf;
  char GetChar() {
    if (front == end) {
      end = buf + fread(front = buf, 1, L, stdin);
      if (front == end) return -1;
    }
    return *(front++);
  }
}

template <typename T>
inline void qr(T &x) {
  char ch = IPT::GetChar(), lst = ' ';
  while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
  while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
  if (lst == '-') x = -x;
}

namespace OPT {
  char buf[120];
}

template <typename T>
inline void qw(T x, const char aft, const bool pt) {
  if (x < 0) {x = -x, putchar('-');}
  int top=0;
  do {OPT::buf[++top] = static_cast<char>(x % 10 + '0');} while (x /= 10);
  while (top) putchar(OPT::buf[top--]);
  if (pt) putchar(aft);
}

const int maxn = 100005;

int n, dn;
ll ans;
ll MU[maxn], odd[maxn], eve[maxn];
std::set<int>s;

void check(const int x);
void upd(const int x);
void calc(const int ll, const int rr, const int v);

int main() {
  freopen("1.in", "r", stdin);
  qr(n); dn = n + 1;
  s.insert(0); s.insert(n + 1);
  for (int i = 1; i <= n; ++i) {
    upd(i);
  }
  int q = 0, x;
  qr(q);
  while (q--) {
    x = 0; qr(x);
    upd(x);
    printf("%lld\n", ans);
  }
  return 0;
}

inline int lowbit(const int x) { return x & -x; }

void update(ll *const a, int p, const ll v) {
  while (p <= dn) {
    a[p] += v;
    p += lowbit(p);
  }
}

ll query(ll *const a, int p) {
  ll _ret = a[p];
  do _ret += a[p -= lowbit(p)]; while (p);
  return _ret;
}

void upd(const int x) {
  ll y = 0; qr(y);
  auto v = s.lower_bound(x);
  auto l = v, r = v;
  --l; ++r;
  if (l != s.begin()) --l;
  if ((r != s.end()) && (*v == x)) ++r;
  if (r == s.end()) --r;
  calc(*l, *r, -1);
  update(x & 1 ? odd : eve, x, y - MU[x]); MU[x] = y;
  check(x);
  if (x != 1) check(x - 1);
  if (x != n) check(x + 1);
  calc(*l, *r, 1);
}

void check(const int x) {
  if ((MU[x] > MU[x - 1]) != (MU[x] < MU[x + 1])) s.insert(x);
  else s.erase(x);
}

void calc(const int ll, const int rr, const int v) {
  auto l = s.lower_bound(ll), r = s.lower_bound(rr);
  while (r != l) {
    auto t = r; --t;
    if (MU[*t] < MU[*r]) {
      auto ad = *r & 1 ? odd : eve;
      ans += v * (query(ad, *r) - query(ad, *t));
    } else {
      auto ad = *t & 1 ? odd : eve;
      ans += v * (query(ad, *r - 1) - query(ad, *t));
      auto l0 = r, r0 = r;
      if (l0 != s.end()) --l0;
      ++r0; if (r0 == s.end()) --r0;
      if ((!((*r - *l0) & 1)) && (!((*r0 - *r) & 1))) {
        ans += MU[*r] * v;
      }
    }
    --r;
  }
  if (MU[*l] >= MU[*l + 1]) return;
  auto l0 = r, r0 = r;
  if (l0 != s.end()) --l0;
  ++r0; if (r0 == s.end()) --r0;
  if ((!((*r - *l0) & 1)) && (!((*r0 - *r) & 1))) {
    ans += MU[*r] * v;
  }
}

Posted by NCllns on Sat, 29 Jun 2019 16:44:21 -0700