C. The Ancient Wizards' Capes

C. The Ancient Wizards' Capes

Problem Statement

There are nn wizards in a row, numbered 1 to nn from left to right. Each wizard has an invisibility cape that can be worn on either their left or right side.

Harry walks from the position of wizard 1 to the position of wizard nn (1n1051 \le n \le 10^5). At each wizard’s position ii, he records the total number of wizards he can see.

A wizard at position jj is visible from position ii if:

  • Wizard jj wears their cape on their left side, and iji \ge j.
  • Wizard jj wears their cape on their right side, and iji \le j.

Note that wizard ii is always visible from their own position, ii.

You have deciphered Harry’s old list, which is an array aa of nn elements. The ii-th element, aia_i (1ain1 \le a_i \le n), is the number of wizards Harry saw from position ii.

Your task is to determine how many of all possible cape arrangements are consistent with the data in list aa.


Solution Explanation

The core of this problem lies in understanding the relationship between the number of visible wizards at adjacent positions, aia_i and ai1a_{i-1}. This relationship will reveal the relative orientation of the capes of wizard i1i-1 and wizard ii.

Let’s denote Ck=1C_k=1 if wizard kk wears their cape on the left, and Ck=0C_k=0 if they wear it on the right.

According to the problem definition, the number of wizards visible from position ii, aia_i, is the sum of:

  1. Wizards jij \le i with capes on their left side.
  2. Wizards jij \ge i with capes on their right side.

This can be formulated as: ai=k=1iCk+k=in(1Ck)a_i = \sum_{k=1}^{i} C_k + \sum_{k=i}^{n} (1 - C_k)

Now, let’s write the same formula for position i1i-1: ai1=k=1i1Ck+k=i1n(1Ck)a_{i-1} = \sum_{k=1}^{i-1} C_k + \sum_{k=i-1}^{n} (1 - C_k)

Let’s find the difference, aiai1a_i - a_{i-1}: aiai1=(k=1iCkk=1i1Ck)+(k=in(1Ck)k=i1n(1Ck))a_i - a_{i-1} = \left(\sum_{k=1}^{i} C_k - \sum_{k=1}^{i-1} C_k\right) + \left(\sum_{k=i}^{n} (1 - C_k) - \sum_{k=i-1}^{n} (1 - C_k)\right)

The first part simplifies to CiC_i. The second part simplifies to (1Ci1)-(1 - C_{i-1}). So, the relationship is: aiai1=Ci(1Ci1)=Ci+Ci11a_i - a_{i-1} = C_i - (1 - C_{i-1}) = C_i + C_{i-1} - 1

Rearranging this gives us: Ci+Ci1=aiai1+1C_i + C_{i-1} = a_i - a_{i-1} + 1

This equation tells us that the sum of the cape orientations for two adjacent wizards (i1i-1 and ii) is determined by the difference in their visibility counts (aiai1a_i - a_{i-1}). Let’s analyze the possible cases for the difference aiai1a_i - a_{i-1}:

  1. aiai1=1a_i - a_{i-1} = 1: Ci+Ci1=1+1=2C_i + C_{i-1} = 1 + 1 = 2. Since CkC_k can only be 0 or 1, this means Ci=1C_i=1 and Ci1=1C_{i-1}=1. Both wizards wear their capes on the left.
  2. aiai1=1a_i - a_{i-1} = -1: Ci+Ci1=1+1=0C_i + C_{i-1} = -1 + 1 = 0. This means Ci=0C_i=0 and Ci1=0C_{i-1}=0. Both wizards wear their capes on the right.
  3. aiai1=0a_i - a_{i-1} = 0: Ci+Ci1=0+1=1C_i + C_{i-1} = 0 + 1 = 1. This means one wizard has a left cape (1) and the other has a right cape (0). Their capes are in opposite directions.

This observation is key: the relative orientation of cape ii to cape i1i-1 is uniquely determined. If we know the orientation of the first wizard’s cape, we can determine the orientation for all subsequent wizards one by one.

This leaves only two possible valid arrangements for the entire row of wizards:

  • One arrangement starting with wizard 1’s cape on the left.
  • One arrangement starting with wizard 1’s cape on the right.

Our algorithm is as follows:

  1. Test the first possibility: Assume wizard 1 has a left cape.
  2. Iterate from i=2i=2 to nn, using the relationship derived above to determine the cape orientation for wizard ii based on aia_i, ai1a_{i-1}, and the now-known orientation of wizard i1i-1.
  3. After determining the full arrangement, we must verify it. Calculate the visibility array vis from scratch based on this arrangement and check if vis[i] == a[i] for all ii.
  4. If the arrangement is valid, we count it as one solution.
  5. Test the second possibility: Repeat the process, this time assuming wizard 1 has a right cape.
  6. If this second arrangement is valid, we add it to our count.
  7. The final answer is the total count, which can be 0, 1, or 2.
View Code
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <tuple>
#include <vector>
using namespace std;
#define int long long
// #define mod 1000000007

#define N 500005
void solve() {
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    vector<bool> a_side(n, false);  // false; visibile from left
    for (int i = 1; i < n; i++) {
        if (a[i] == a[i - 1]) {
            a_side[i] = !a_side[i - 1];
        } else {
            a_side[i] = a_side[i - 1];
        }
    }
    auto func_verify = [&](vector<int> &a, vector<bool> &a_side) -> bool {
        int vis_t = 0;
        vector<int> vis(n, 0);
        for (int i = 0; i < n; i++) {
            vis[i] += vis_t;
            vis_t += a_side[i] == false ? 1 : 0;
        }
        vis_t = 0;
        for (int i = n - 1; i >= 0; i--) {
            vis[i] += vis_t;
            vis_t += a_side[i] == true ? 1 : 0;
        }
        // if vis == a, return true
        for (int i = 0; i < n; i++) {
            if (vis[i]+1 != a[i]) {
                return false;
            }
        }
        return true;
    };
    int ans = func_verify(a, a_side) ? 1 : 0;
    a_side[0] = true;

    for (int i = 1; i < n; i++) {
        if (a[i] == a[i - 1]) {
            a_side[i] = !a_side[i - 1];
        } else {
            a_side[i] = a_side[i - 1];
        }
    }
    ans += func_verify(a, a_side) ? 1 : 0;
    cout << ans << endl;

}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifdef DEBUG
    freopen("./input.txt", "r", stdin);
#endif
    int t;
    cin >> t;
    while (t--) {
#ifdef DEBUG
        static int test_num = 1;
        cout << "test case: " << test_num++ << endl;
#endif
        solve();
    }
}