题意:告诉一块玻璃长宽,长宽小于200000, Q个询问每次横向或者纵向切割,每次询问输出最大的玻璃面积
题解:一开始想顺着做,发现行不通,可以倒过来想,每次合并两个,最大值只可能是合并的这两个或者是原序列的最大值,这里用set代替链表
#include <bits/stdc++.h> #define ll long long #define maxn 200100 using namespace std; set<ll >hh, ww; char ch[maxn]; ll a[maxn], b[maxn], ans[maxn]; int main(){ ll h, w, n, t, temp, mx, numa = 0,numb = 0, t1, t2; scanf("%lld%lld%lld", &w, &h, &n); for(ll i=0;i<n;i++){ getchar(); scanf("%c%lld", &ch[i], &a[i]); if(ch[i] == 'H') hh.insert(a[i]); else ww.insert(a[i]); } hh.insert(0);hh.insert(h); ww.insert(0);ww.insert(w); ll mxh=0,mxw=0; auto it = hh.begin(); while(1){ auto ito = it; ito++; if(ito == hh.end()) break; mxh = max(mxh, *ito-*it); it = ito; } auto it1 = ww.begin(); while(1){ auto ito = it1; ito++; if(ito == ww.end()) break; mxw = max(mxw, *ito-*it1); it1 = ito; } ans[n-1] = mxh*mxw; for(ll i=n-1;i>=0;i--){ if(ch[i] == 'H'){ auto it = hh.lower_bound(a[i]); mxh = max(mxh, *(++it)-*(----it)); hh.erase(a[i]); ans[i-1] = mxh*mxw; } else { auto it = ww.lower_bound(a[i]); t = *(++it)-*(----it); mxw = max(mxw, t); ww.erase(a[i]); ans[i-1] = mxh*mxw; } } for(ll i=0;i<n;i++) printf("%lld\n", ans[i]); return 0; }