From b6176683ab4bdc959dab3316f260bcc3000a43a0 Mon Sep 17 00:00:00 2001 From: oncsr Date: Fri, 11 Jul 2025 12:34:44 +0900 Subject: [PATCH] =?UTF-8?q?[20250711]=20BOJ=20/=20D4=20/=20=ED=9E=88?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EA=B7=B8=EB=9E=A8=20=ED=95=98=EB=82=98=20?= =?UTF-8?q?=EB=B9=BC=EA=B8=B0=20/=20=EA=B6=8C=ED=98=81=EC=A4=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\353\202\230 \353\271\274\352\270\260.md" | 406 ++++++++++++++++++ 1 file changed, 406 insertions(+) create mode 100644 "khj20006/202507/11 BOJ D4 \355\236\210\354\212\244\355\206\240\352\267\270\353\236\250 \355\225\230\353\202\230 \353\271\274\352\270\260.md" diff --git "a/khj20006/202507/11 BOJ D4 \355\236\210\354\212\244\355\206\240\352\267\270\353\236\250 \355\225\230\353\202\230 \353\271\274\352\270\260.md" "b/khj20006/202507/11 BOJ D4 \355\236\210\354\212\244\355\206\240\352\267\270\353\236\250 \355\225\230\353\202\230 \353\271\274\352\270\260.md" new file mode 100644 index 00000000..2a0ea6f5 --- /dev/null +++ "b/khj20006/202507/11 BOJ D4 \355\236\210\354\212\244\355\206\240\352\267\270\353\236\250 \355\225\230\353\202\230 \353\271\274\352\270\260.md" @@ -0,0 +1,406 @@ +# C++ + +```cpp +#include +using namespace std; +using ll = long long; + +int N, s[500001]{}, e[500001]{}, l[500001]{}, r[500001]{}; +ll h[500001]{}, v[500001]{}, ans[500001]{}; + +ll seg[1048576]{}; + +class DisjointSet { + public: + int r[500001]{}; + DisjointSet() { + for(int i=1;i<=500000;i++) r[i] = i; + } + int f(int x) {return x==r[x] ? x : r[x]=f(r[x]);} + void uni(int a, int b) { + int x = f(a), y = f(b); + if(x == y) return; + r[x] = y; + } +}; + +DisjointSet le, ri; + +void prop(int s, int e, int n){ + if(seg[n]) { + if(s != e) { + seg[n*2] = max(seg[n*2], seg[n]); + seg[n*2+1] = max(seg[n*2+1], seg[n]); + seg[n] = 0; + } + } +} + +void upt(int s, int e, int l, int r, ll v, int n) { + prop(s, e, n); + if (l > r || l > e || r < s) return; + if (l <= s && e <= r) { + seg[n] = max(seg[n], v); + if(s != e) { + seg[n*2] = max(seg[n*2], v); + seg[n*2+1] = max(seg[n*2+1], v); + } + return; + } + int m = (s + e) >> 1; + upt(s, m, l, r, v, n * 2); + upt(m + 1, e, l, r, v, n * 2 + 1); +} + +ll find(int s, int e, int i, int n) { + prop(s,e,n); + if(s == e) return seg[n]; + int m = (s+e)>>1; + if(i <= m) return find(s,m,i,n*2); + return find(m+1,e,i,n*2+1); +} + +int main(){ + cin.tie(0)->sync_with_stdio(0); + + cin>>N; + for(int i=1;i<=N;i++) { + s[i] = i; + e[i] = i; + cin>>h[i]; + } + + stack> s1; + for(int i=N;i>=1;i--) { + while(!s1.empty() && s1.top().first > h[i]) { + int x = s1.top().second; + l[x] = i; + s1.pop(); + } + s1.push({h[i],i}); + } + + stack> s2; + for(int i=1;i<=N;i++) { + while(!s2.empty() && s2.top().first > h[i]) { + int x = s2.top().second; + r[x] = i; + s2.pop(); + } + s2.push({h[i],i}); + } + + vector> infos; + for(int i=1;i<=N;i++) infos.push_back({h[i],i}); + sort(infos.begin(), infos.end(), [](auto a, auto b) -> bool { + return a.first == b.first ? a.second < b.second : a.first > b.first; + }); + + bitset<500001> vis; + + for(int x=0;x> li; + while(x1 && vis[idx-1]) { + le.uni(idx, idx-1); + ri.uni(idx-1, idx); + } + if(idx1 && vis[idx-1]) s[idx] = le.f(idx-1); + else s[idx] = idx; + + if(idx1 && vis[l[idx]-1]) L = le.f(l[idx]-1); + else L = l[idx]; + ans[l[idx]] = max(ans[l[idx]], h[idx] * (e[idx] - L)); + } + + if(r[idx]) { + int R = 0; + if(r[idx] r || l > e || r < s) return; + if (l <= s && e <= r) { + tree[n] = Math.max(tree[n], v); + if(s != e) { + tree[n*2] = Math.max(tree[n*2], v); + tree[n*2+1] = Math.max(tree[n*2+1], v); + } + return; + } + int m = (s + e) >> 1; + update(s, m, l, r, v, n * 2); + update(m + 1, e, l, r, v, n * 2 + 1); + } + + long find(int s, int e, int i, int n) { + propagation(s, e, n); + if(s == e) return tree[n]; + int m = (s+e)>>1; + if(i <= m) return find(s,m,i,n*2); + return find(m+1,e,i,n*2+1); + } + +} + +public class Main { + + static IOController io; + + // + + static int N; + static int[] s, e, l, r; + static long[] h, v, ans; + static DisjointSet left, right; + static SegTree seg; + + public static void main(String[] args) throws Exception { + + io = new IOController(); + + init(); + solve(); + + io.close(); + } + + public static void init() throws Exception { + + N = io.nextInt(); + left = new DisjointSet(N + 1); + right = new DisjointSet(N + 1); + s = new int[N + 1]; + e = new int[N + 1]; + h = new long[N + 1]; + for (int i = 1; i <= N; i++) { + h[i] = io.nextLong(); + s[i] = i; + e[i] = i; + } + l = new int[N + 1]; + r = new int[N + 1]; + v = new long[N + 1]; + ans = new long[N+1]; + seg = new SegTree(N); + + } + + static void solve() throws Exception { + + // 정보 정렬 후 분리 집합으로 v, s, e 구하기 + // 이 때, lazy등으로 max갱신까지 같이 할 수 있으면 하기 + + // l 구하기 + Stack s1 = new Stack<>(); + for(int i=N;i>=1;i--) { + while(!s1.isEmpty() && s1.peek()[0] > h[i]) l[s1.pop()[1]] = i; + s1.push(new int[]{(int)h[i], i}); + } + + // r 구하기 + Stack s2 = new Stack<>(); + for(int i=1;i<=N;i++) { + while(!s2.isEmpty() && s2.peek()[0] > h[i]) r[s2.pop()[1]] = i; + s2.push(new int[]{(int)h[i], i}); + } + + long[][] infos = new long[N][2]; + for (int i = 1; i <= N; i++) infos[i - 1] = new long[]{h[i], i}; + Arrays.sort(infos, (a, b) -> a[0] == b[0] ? Long.compare(a[1], b[1]) : Long.compare(b[0], a[0])); + + boolean[] vis = new boolean[N+1]; + + for(int x=0;x list = new ArrayList<>(); + while(x1 && vis[idx-1]) { + left.union(idx, idx-1); + right.union(idx-1, idx); + } + if(idx1 && vis[idx-1]) { + s[idx] = left.find(idx-1); + } + else s[idx] = idx; + + if(idx1 && vis[l[idx]-1]) L = left.find(l[idx]-1); + else L = l[idx]; + ans[l[idx]] = Math.max(ans[l[idx]], h[idx] * (e[idx] - L)); + } + + if(r[idx] != 0) { + int R = 0; + if(r[idx]