---
# System prepended metadata

title: '2020-2021 ACM-ICPC, Asia Seoul Regional Contest'

---

2020-2021 ACM-ICPC, Asia Seoul Regional Contest
===
比賽鏈結
---
https://codeforces.com/gym/102920/

比賽影片
---
No

記分板

---
![image](https://hackmd.io/_uploads/SkjEkVJCC.png)


題解
---
### A. Autonomous Vehicle 
---
#### 題目摘要

#### 想法

:::spoiler 實作
```cpp=

```
:::

### B. Commemorative Dice
---
#### 題目摘要


#### 想法
隊友秒ㄌ

:::spoiler 實作

```cpp=
#pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
using namespace std;
#define ZTMYACANESOCUTE ios_base::sync_with_stdio(0), cin.tie(0)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define debug(x) cerr << #x << " = " << x << '\n';
#define rep(X, a, b) for(int X = a; X < b; ++X)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pld pair<ld, ld>
#define ld long double
#define F first
#define S second

pii operator + (const pii &p1, const pii &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pii operator - (const pii &p1, const pii &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }
pll operator + (const pll &p1, const pll &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pll operator - (const pll &p1, const pll &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }

template<class T> bool chmin(T &a, T b) { return (b < a && (a = b, true)); }
template<class T> bool chmax(T &a, T b) { return (a < b && (a = b, true)); }

#define lpos pos << 1
#define rpos pos << 1 | 1
 
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << "," << p.second << ')'; }
template<typename A> ostream& operator << (ostream &os, const vector<A> &p) { for(const auto &a : p) os << a << " "; os << '\n'; return os; }
 
const int MAXN = 2e5 + 5, MOD = 998244353, IINF = 1e9 + 7, MOD2 = 1000000007;
const double eps = 1e-9;
const ll LINF = 1e18L + 5;
const int B = 320;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// int get_rand(int l, int r){ return uniform_int_distribution<int>(l, r)(rng); }
 
ll fpow(ll x, ll exp, ll mod = LLONG_MAX){ ll res = 1; while(exp){ if(exp & 1) res = res * x % mod; x = x * x % mod; exp >>= 1;} return res; }

void solve() {
    vector<int> a(6), b(6);
    rep (i, 0, 6) cin >> a[i];
    rep (i, 0, 6) cin >> b[i];
    int ans = 0;
    rep (i, 0, 6) rep (j, 0, 6) {
        if (a[i] > b[j]) ans++;
    }
    int g = __gcd(ans, 36);
    cout << ans / g << '/' << 36 / g << '\n';
}
 
int main() {
    ZTMYACANESOCUTE;
    int T = 1;
    // cin >> T;
    while (T--) {
        solve();
    }
}
```
:::


### C. Dessert Café
---
#### 題目摘要
給定幾個公寓的預定地，所有點都可以是一個預選地，然後定義一個好的預選地p為對於其他所有預選地q，他都可以找到一個公寓預定地k使得dis(p,k) < dis(q,k)，要你輸出所有好的點

#### 想法
可以觀察到，如果一個點有兩個子樹都有公寓預定地，那麼這個點對於B子樹的預定地的距離，一定比A子樹的所有點短，反之亦然，因此只要關注每個點是否有兩個以上的子樹有公寓預定地即可，記得加上公寓預定地本身

:::spoiler 實作
```cpp=
#pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
using namespace std;
#define ZTMYACANESOCUTE ios_base::sync_with_stdio(0), cin.tie(0)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define debug(x) cerr << #x << " = " << x << '\n';
#define rep(X, a, b) for(int X = a; X < b; ++X)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pld pair<ld, ld>
#define ld long double
#define F first
#define S second

pii operator + (const pii &p1, const pii &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pii operator - (const pii &p1, const pii &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }
pll operator + (const pll &p1, const pll &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pll operator - (const pll &p1, const pll &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }

template<class T> bool chmin(T &a, T b) { return (b < a && (a = b, true)); }
template<class T> bool chmax(T &a, T b) { return (a < b && (a = b, true)); }

#define lpos pos << 1
#define rpos pos << 1 | 1

template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << "," << p.second << ')'; }
template<typename A> ostream& operator << (ostream &os, const vector<A> &p) { for(const auto &a : p) os << a << " "; os << '\n'; return os; }

const int MAXN = 2e5 + 5, MOD = 998244353, IINF = 1e9 + 7, MOD2 = 1000000007;
const double eps = 1e-9;
const ll LINF = 1e18L + 5;
const int B = 320;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// int get_rand(int l, int r){ return uniform_int_distribution<int>(l, r)(rng); }

ll fpow(ll x, ll exp, ll mod = LLONG_MAX){ ll res = 1; while(exp){ if(exp & 1) res = res * x % mod; x = x * x % mod; exp >>= 1;} return res; }

void solve() {
    int n, k; cin >> n >> k;
    vector<vector<pii>> adj(n);
    rep (i, 0, n - 1) {
        int a, b, c; cin >> a >> b >> c;
        a--, b--;
        adj[a].pb({b, c});
        adj[b].pb({a, c});
    } 
    vector<int> col(n, 0);
    rep (i, 0, k) {
        int a; cin >> a;
        a--;
        col[a] = 1;
    }
    vector<int> sz(n, 0), dep(n);
    int ans = 0;
    auto dfs = [&](auto self, int u, int pa) -> void {
        sz[u] = col[u];
        int cnt = 0;
        for (auto [v, w] : adj[u]) {
            if (v == pa) continue;
            dep[v] = dep[u] + 1;
            self(self, v, u);
            sz[u] += sz[v];
            cnt += sz[v] > 0;
        }
        if (k - sz[u] > 0) cnt++;
        if (col[u] == 1) ans++;
        else {
            if (cnt >= 2) ans++;
        }
    };
    dep[0] = 0;
    dfs(dfs, 0, -1);
    cout << ans << '\n';
}

int main() {
    ZTMYACANESOCUTE;
    int T = 1;
    // cin >> T;
    while (T--) {
        solve();
    }
}
```
:::

### D. Electric Vehicle
---
#### 題目摘要
#### 想法


:::spoiler 實作
```cpp=

```
:::

### E. Imprecise Computer
---
#### 題目摘要
有$n$個人雙雙比賽，編號$1到n$。編號$i$和編號$j$比賽$(i>j)$為，若$i-j<2$，則$j$有可能打贏$i$，否則一定$i$打贏$j$。總共會有兩輪比賽，定義$r_i(k)$為第$i$場第$k$個人打贏多少人，題目會給你一個序列$d$，$d(i)=|r_1(i)-r_2(i)|,\ \ 1\le i\le n$的值，問有沒有一組比賽滿足它
#### 想法
在同一場比賽中，將第$i和i+1$的人同時考慮，若$i打贏i+1$，則$r(i)$會+1，$r(i+1)$會-1，否則$r(i)=i,\ r(i+1)=i+1$。而當考慮到兩場比賽的組合，相當於$d(i)與d(i+1)$的改變量有$(1, -1),(0, 0),(-1, 1)$三種可能
因此題目轉換成對一個初始為0的序列做操作，操作能對$i與i+1$的位置增加$(1, -1),(0, 0),(-1, 1)$，問能不能元素取絕對值是$d$。記一個$dp_{i, j}$為從$1到i-1$的位置元素的絕對值已經滿足$d$了，且第$i$個元素是$j$，好好轉移就好了
:::spoiler 實作
```cpp=
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define ORENOOSHIKYOUMOKAWAIII ios::sync_with_stdio(0), cin.tie(0)
#define F first
#define S second
 
template<class T> bool chmin(T &a, T b){return (a>b)?a=b, true:false;}
template<class T> bool chmax(T &a, T b){return (a<b)?a=b, true:false;}
template<class T> T fpow(T x, ll k){T res=1;while(k){if (k&1) res=res*x;x=x*x, k>>=1;}return res;}
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int get_rand(int l, int r){return uniform_int_distribution<int>(l, r)(rng);}
 
const double eps=1e-9;
const int IINF=1e9+7;
const ll LINF=1e18+5;
const int MOD1=998244353, MOD2=1e9+7;
 
template <class T> istream& operator>> (istream& cin, pair<T, T>& tmp){cin >> tmp.F >> tmp.S;return cin;} 
template <class T> istream& operator>> (istream& cin, vector<T>& tmp){for(auto &v:tmp) cin >> v;return cin;}
template <class T> ostream& operator<< (ostream& cout, pair<T, T>& tmp){cout << tmp.F << ' ' << tmp.S;return cout;} 
template <class T> ostream& operator<< (ostream& cout, vector<T>& tmp){for(auto v:tmp) cout << v << ' ';return cout;}
 
const int N=1e6+10;
bool dp[N][5];
 
void _solve(){
    int n;
    cin >> n;
    vector<int> v(n);
    cin >> v;
    if (v[0]==0) dp[1][2]=1;
    else if (v[0]==1) dp[1][1]=dp[1][3]=1;
    for(int i=2;i<n;i++){
        for(int j=-2;j<=2;j++) if (dp[i-1][j+2]) {
            if (abs(j+1)==v[i-1]) dp[i][1]=1;
            if (abs(j)==v[i-1]) dp[i][2]=1;
            if (abs(j-1)==v[i-1]) dp[i][3]=1;
        }
    }
    bool ans=(dp[n-1][2+v[n-1]]||dp[n-1][2-v[n-1]]);
    cout << (ans?"YES":"NO") << '\n';
}
 
int main(){
    ORENOOSHIKYOUMOKAWAIII;
    int _t=1;
    //cin >> _t;
    while(_t--) _solve();
}
```
:::

### F. Ink Mix
---
#### 題目摘要
#### 想法

:::spoiler 實作
```cpp=

```
:::

### G. Mobile Robot
---
#### 題目摘要
好好移動機器人們，讓機器人們照編號成等差數列，並使最大移動量最小
#### 想法
將$d\times i-a_i$存起來排序將算最大與最小的差除以二，再把$a$反轉後再做一次

:::spoiler 實作
```cpp=
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define ORENOOSHIKYOUMOKAWAIII ios::sync_with_stdio(0), cin.tie(0)
#define F first
#define S second

template <class T> istream& operator>> (istream& cin, pair<T, T>& tmp){cin >> tmp.F >> tmp.S;return cin;} 
template <class T> istream& operator>> (istream& cin, vector<T>& tmp){for(auto &v:tmp) cin >> v;return cin;}
template <class T> ostream& operator<< (ostream& cout, pair<T, T>& tmp){cout << tmp.F << ' ' << tmp.S;return cout;} 
template <class T> ostream& operator<< (ostream& cout, vector<T>& tmp){for(auto v:tmp) cout << v << ' ';return cout;}

void _solve(){
    int n;
    ll d;
    cin >> n >> d;
    vector<ll> a(n), v(n);
    cin >> a;
    for(int i=0;i<n;i++) v[i]=d*i-a[i];
    sort(v.begin(), v.end());
    ld mid=(v[0]+v.back())/2.0;
    ld ans=(mid-v[0]);
    reverse(a.begin(), a.end());
    for(int i=0;i<n;i++) v[i]=d*i-a[i];
    sort(v.begin(), v.end());
    mid=(v[0]+v.back())/2.0;
    chmin(ans, mid-v[0]);
    cout << fixed << setprecision(1) << ans << '\n';
}

int main(){
    ORENOOSHIKYOUMOKAWAIII;
    int _t=1;
    //cin >> _t;
    while(_t--) _solve();
}
```
:::


### H. Needle
---
#### 題目摘要
給上中下三條等距直線以及他們上面的一些點，求有多少$\,(u, m, l)\,$使得上中下三點共線

$1 \leq n_u, n_m, n_l \leq 50,000$
$x$-coordinates of the holes are integers between $−30,000$ and $30,000$.
#### 想法
範圍很bitset，不如往bitset想。
然後就發現只要枚舉位移距離後，把上面右移下面左移，及上面左移下面右移
三層答案$\&$起來就好，記得對一條鉛直線的不要重複算。

:::spoiler 實作
```cpp=
#pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
using namespace std;
#define ZTMYACANESOCUTE ios_base::sync_with_stdio(0), cin.tie(0)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define debug(x) cerr << #x << " = " << x << '\n';
#define rep(X, a, b) for(int X = a; X < b; ++X)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pld pair<ld, ld>
#define ld long double
#define F first
#define S second

pii operator + (const pii &p1, const pii &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pii operator - (const pii &p1, const pii &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }
pll operator + (const pll &p1, const pll &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pll operator - (const pll &p1, const pll &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }

template<class T> bool chmin(T &a, T b) { return (b < a && (a = b, true)); }
template<class T> bool chmax(T &a, T b) { return (a < b && (a = b, true)); }

#define lpos pos << 1
#define rpos pos << 1 | 1
 
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << "," << p.second << ')'; }
template<typename A> ostream& operator << (ostream &os, const vector<A> &p) { for(const auto &a : p) os << a << " "; os << '\n'; return os; }
 
const int MAXN = 2e5 + 5, MOD = 998244353, IINF = 1e9 + 7, MOD2 = 1000000007;
const double eps = 1e-9;
const ll LINF = 1e18L + 5;
const int B = 320;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// int get_rand(int l, int r){ return uniform_int_distribution<int>(l, r)(rng); }
 
ll fpow(ll x, ll exp, ll mod = LLONG_MAX){ ll res = 1; while(exp){ if(exp & 1) res = res * x % mod; x = x * x % mod; exp >>= 1;} return res; }

void solve() {
    const int s = 30000;
    bitset<65536> up, down, mid;
    int n; cin >> n;
    rep (i, 0, n) {
        int x; cin >> x;
        up[s + x] = 1;
    }
    int n2; cin >> n2;
    rep (i, 0, n2) {
        int x; cin >> x;
        mid[s + x] = 1;
    }
    int n3; cin >> n3;
    rep (i, 0, n3) {
        int x; cin >> x;
        down[s + x] = 1;
    }
    ll ans = (up & mid & down).count();
    rep (i, 1, s + 1) {
        ans += ((up >> i) & mid & (down << i)).count();
        ans += ((up << i) & mid & (down >> i)).count();
    }
    cout << ans << '\n';
}
 
int main() {
    ZTMYACANESOCUTE;
    int T = 1;
    // cin >> T;
    while (T--) {
        solve();
    }
}
```
:::

### I. Stock Analysis
---
#### 題目摘要
#### 想法

:::spoiler 實作
```cpp=


```
:::


### J. Switches
---
#### 題目摘要

給一個$N \times N$的矩陣，對每一行$i$詢問需要哪幾行做至多一次的xor操作使得這行剩下$a_{{i}{i}} = 1$。

#### 想法
做高斯消並記錄操作方法
避免算到有操作偶數次的，我對操作方法也做xor
:::spoiler 實作
```cpp=
#pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
using namespace std;
#define ZTMYACANESOCUTE ios_base::sync_with_stdio(0), cin.tie(0)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define debug(x) cerr << #x << " = " << x << '\n';
#define rep(X, a, b) for(int X = a; X < b; ++X)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pld pair<ld, ld>
#define ld long double
#define F first
#define S second

pii operator + (const pii &p1, const pii &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pii operator - (const pii &p1, const pii &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }
pll operator + (const pll &p1, const pll &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pll operator - (const pll &p1, const pll &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }

template<class T> bool chmin(T &a, T b) { return (b < a && (a = b, true)); }
template<class T> bool chmax(T &a, T b) { return (a < b && (a = b, true)); }

#define lpos pos << 1
#define rpos pos << 1 | 1
 
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << "," << p.second << ')'; }
template<typename A> ostream& operator << (ostream &os, const vector<A> &p) { for(const auto &a : p) os << a << " "; os << '\n'; return os; }
 
const int MAXN = 2e5 + 5, MOD = 998244353, IINF = 1e9 + 7, MOD2 = 1000000007;
const double eps = 1e-9;
const ll LINF = 1e18L + 5;
const int B = 320;

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// int get_rand(int l, int r){ return uniform_int_distribution<int>(l, r)(rng); }
 
ll fpow(ll x, ll exp, ll mod = LLONG_MAX){ ll res = 1; while(exp){ if(exp & 1) res = res * x % mod; x = x * x % mod; exp >>= 1;} return res; }

void solve() {
    int n; cin >> n;
    vector<int> basis(n, -1);
    vector<bitset<505>> bst;
    rep (i, 0, n) {
        bitset<505> tmp;
        rep (j, 0, n) {
            int a; cin >> a;
            tmp = tmp << 1;
            tmp[0] = a;
        }
        bst.pb(tmp);
    }
    vector<bitset<505>> ope(n);
    rep (i, 0, n) {
        bitset<505> cur;
        cur[i] = 1;
        for (int j = n - 1; j >= 0; --j) if (bst[i][j]) {
            if (basis[j] == -1) {
                basis[j] = i;
                for (int k = j - 1; k >= 0; --k) if (basis[k] != -1) {
                    if (bst[basis[j]][k]) {
                        cur ^= ope[k];
                        bst[i] ^= bst[basis[k]];
                    }
                }
                rep (k, j + 1, n) if (basis[k] != -1) {
                    if (bst[basis[k]][j]) {
                        ope[k] ^= cur;
                        bst[basis[k]] ^= bst[i];
                    }
                }
                ope[j] = cur;
                break;
            } else {
                bst[i] ^= bst[basis[j]];
                cur ^= ope[j];
            }
        }
    }
    rep (i, 0, n) if (basis[i] == -1) {
        cout << -1 << '\n';
        return;
    }
    for (int i = n - 1; i >= 0; --i) {
        rep (j, 0, n) if (ope[i][j]) {
            cout << j + 1 << ' ';
        }
        cout << '\n';
    }
}
 
int main() {
    ZTMYACANESOCUTE;
    int T = 1;
    // cin >> T;
    while (T--) {
        solve();
    }
}
```
:::


### K. Tiling Polyomino
---
#### 題目摘要
給一個無洞並且每個點的鄰居至少會有2個以上的多邊形，問能不能用給定的方塊組成

#### 想法
給定的方塊能把長度為2以上的一行填滿，所以要處理的只有一個的情況，若那格上左右都是豎的，直接把那個變豎的，不然將那格與它下面那格變豎的，給定所有方格要是橫的還豎的，接下來只要跑橫的與豎的判一槓長度奇偶構造就好

:::spoiler 實作
```cpp=
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define F first
#define S second

const int N=1005;
char a[N][N];
char ans[N][N];

void _solve(){
    int n;
    cin >> n;
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin >> a[i][j];
    for(int i=0;i<=n+1;i++) a[i][0]=a[i][n+1]=a[0][i]=a[n+1][i]='0';
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if (a[i][j]=='1'&&a[i][j-1]!='1'&&a[i][j+1]!='1'){
        a[i][j]='2';
        if (a[i-1][j]!='2'||a[i][j-1]!='2'||a[i][j+1]!='2'){
            a[i+1][j]='2';
        }
    }
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if (a[i][j]=='0') ans[i][j]='0';
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if (a[i][j]=='1'){
        int k=j;
        while(a[i][k]=='1') ans[i][k++]='2';
        if ((k-j)&1) ans[i][j]=ans[i][j+1]=ans[i][j+2]='4';
        j=k;
    }
    for(int j=1;j<=n;j++) for(int i=1;i<=n;i++) if (a[i][j]=='2'){
        int k=i;
        while(a[k][j]=='2') ans[k++][j]='3';
        if ((k-i)&1) ans[i][j]=ans[i+1][j]=ans[i+2][j]='5';
        i=k;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) cout << ans[i][j];
        cout << '\n';
    }
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int _t=1;
    //cin >> _t;
    while(_t--) _solve();
}
```
:::

### L. Two Buildings
---
#### 題目大綱
給一陣列$h$，求$\max_{1 \leq i < j \leq n} (h_i + h_j) \ast (j − i)$
#### 想法
將所有$h_i$看作二維平面的$(i, h_i)$，複製一份$(i, -h_i)$在下面，可以發現這就是不單調的[超大畫框設置](https://tioj.ck.tp.edu.tw/problems/1283)問題，因此先對上面的點保留$y$軸嚴格遞減的點，確保轉移點的單調性，之後就直接套轉移點單調的優化就好。
:::spoiler 實作
```cpp=
#pragma GCC optimize("O3,unroll-loops")
// #pragma GCC target("avx,popcnt,sse4,abm")
#include<bits/stdc++.h>
using namespace std;
#define ZTMYACANESOCUTE ios_base::sync_with_stdio(0), cin.tie(0)
#define ll long long
#define ull unsigned long long
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define debug(x) cerr << #x << " = " << x << '\n';
#define rep(X, a, b) for(int X = a; X < b; ++X)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pld pair<ld, ld>
#define ld long double
#define F first
#define S second

pii operator + (const pii &p1, const pii &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pii operator - (const pii &p1, const pii &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }
pll operator + (const pll &p1, const pll &p2) { return make_pair(p1.F + p2.F, p1.S + p2.S); }
pll operator - (const pll &p1, const pll &p2) { return make_pair(p1.F - p2.F, p1.S - p2.S); }

template<class T> bool chmin(T &a, T b) { return (b < a && (a = b, true)); }
template<class T> bool chmax(T &a, T b) { return (a < b && (a = b, true)); }

#define lpos pos << 1
#define rpos pos << 1 | 1
 
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << "," << p.second << ')'; }
template<typename A> ostream& operator << (ostream &os, const vector<A> &p) { for(const auto &a : p) os << a << " "; os << '\n'; return os; }
 
const int MAXN = 2e5 + 5, MOD = 998244353, IINF = 1e9 + 7, MOD2 = 1000000007;
const double eps = 1e-9;
const ll LINF = 1e18L + 5;
const int B = 320;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
// int get_rand(int l, int r){ return uniform_int_distribution<int>(l, r)(rng); }
 
ll fpow(ll x, ll exp, ll mod = LLONG_MAX){ ll res = 1; while(exp){ if(exp & 1) res = res * x % mod; x = x * x % mod; exp >>= 1;} return res; }

void solve() {
    int n; cin >> n;
    vector<pll> a, b;
    vector<ll> y(n);
    rep (i, 0, n) {
        ll x; cin >> x;
        y[i] = -x;
        while (!a.empty() && x >= a.back().F) a.pop_back();
        a.pb({x, i});
    }
    int m = a.size();
    auto calc = [&](int i, int j) -> ll {
        return (a[j].F - y[i]) * (a[j].S - i);
    };
    ll ans = 0;
    auto dc = [&](auto self, int l, int r, int ql, int qr) -> void {
        if (l > r) return;
        if (ql == qr) {
            rep (i, l, r + 1) {
                chmax(ans, calc(ql, i));
            }
            return;
        }
        int mid = l + r >> 1, opt;
        ll res = -1;
        rep (i, ql, qr + 1) {
            if (chmax(res, calc(i, mid))) {
                opt = i;
            }
        }
        chmax(ans, res);
        self(self, l, mid - 1, ql, opt);
        self(self, mid + 1, r, opt, qr);
    };
    dc(dc, 0, m - 1, 0, n - 1);
    cout << ans << '\n';
}
 
int main() {
    ZTMYACANESOCUTE;
    int T = 1;
    // cin >> T;
    while (T--) {
        solve();
    }
}
```
:::
