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(); } } ``` :::