Submission #730903

#TimeUsernameProblemLanguageResultExecution timeMemory
730903fatemetmhrFish 2 (JOI22_fish2)C++17
60 / 100
4027 ms11036 KiB
// ~ Be Name Khoda ~ #include <bits/stdc++.h> //#pragma GCC optimize ("Ofast") //#pragma GCC target("avx2") #pragma GCC optimize("unroll-loops,O3") using namespace std; typedef long long ll; typedef pair <int, int> pii; #define pb push_back #define mp make_pair #define all(x) x.begin(), x.end() #define fi first #define se second const int maxn = 2e7 + 10; const int maxn5 = 1e5 + 10; const int maxnt = 5e5 + 10; const int maxn3 = 1e3 + 10; const int mod = 1e9 + 7; const ll inf = 1e18; ll a[maxn5]; int n, chpt = 0; pii ch[maxn]; vector <ll> av; namespace seg{ pii mn[maxnt]; int lazy[maxnt]; ll sum[maxnt], mx[maxnt]; inline pii comb(pii a, pii b){ pii ans = min(a, b); if(a.fi == b.fi) ans.se = a.se + b.se; return ans; } void build(int l, int r, int v){ mn[v] = {0, r - l}; if(r - l == 1) return; int mid = (l + r) >> 1; build(l, mid, v * 2); build(mid, r, v * 2 + 1); } void upd(int l, int r, int id, int v){ if(r - l == 1){ mx[v] = sum[v] = a[id]; return; } int mid = (l + r) >> 1; if(id < mid) upd(l, mid, id, v * 2); else upd(mid, r, id, v * 2 + 1); mx[v] = max(mx[v * 2], mx[v * 2 + 1]); sum[v] = sum[v * 2] + sum[v * 2 + 1]; } void add(int l, int r, int lq, int rq, int val, int v){ if(rq <= l || r <= lq) return; if(lq <= l && r <= rq){ lazy[v] += val; mn[v].fi += val; return; } int mid = (l + r) >> 1; add(l, mid, lq, rq, val, v * 2); add(mid, r, lq, rq, val, v * 2 + 1); mn[v] = comb(mn[v * 2], mn[v * 2 + 1]); mn[v].fi += lazy[v]; } ll get_sum(int l, int r, int lq, int rq, int v){ if(rq <= l || r <= lq) return 0; if(lq <= l && r <= rq) return sum[v]; int mid = (l + r) >> 1; return get_sum(l, mid, lq, rq, v * 2) + get_sum(mid, r, lq, rq, v * 2 + 1); } pii get_min(int l, int r, int lq, int rq, int v){ if(rq <= l || r <= lq) return {mod, 0}; if(lq <= l && r <= rq) return mn[v]; int mid = (l + r) >> 1; pii ans = comb(get_min(l, mid, lq, rq, v * 2), get_min(mid, r, lq, rq, v * 2 + 1)); ans.fi += lazy[v]; return ans; } int get_first(int l, int r, int lq, int rq, ll val, int v){ if(rq <= l || r <= lq || mx[v] < val) return -1; if(r - l == 1) return l; int mid = (l + r) >> 1; int ans = get_first(l, mid, lq, rq, val, v * 2); if(ans != -1) return ans; return get_first(mid, r, lq, rq, val, v * 2 + 1); } int get_last(int l, int r, int lq, int rq, ll val, int v){ if(rq <= l || r <= lq || mx[v] < val) return -1; if(r - l == 1) return l; int mid = (l + r) >> 1; int ans = get_last(mid, r, lq, rq, val, v * 2 + 1); if(ans != -1) return ans; return get_last(l, mid, lq, rq, val, v * 2); } } inline void update(int x, ll y, bool keep){ //cerr << "ya here " << x << ' ' << y << '\n'; if(y == a[x]) return; if(y > a[x]){ ll sum1 = a[x], sum2 = a[x]; int i1 = seg::get_last(0, n, 0, x, a[x] + 1, 1); int i2 = seg::get_first(0, n, x + 1, n, a[x] + 1, 1); while(i1 != -1 && i2 != -1){ ll sum = seg::get_sum(0, n, i1 + 1, i2, 1); if(sum < min(a[i1], a[i2]) && sum - a[x] + y >= min(a[i1], a[i2])){ seg::add(0, n, i1 + 1, i2, -1, 1); if(keep) ch[chpt++] = {i1, i2}; } if(a[i1] <= a[i2]){ sum1 += a[i1]; i1 = seg::get_last(0, n, 0, i1, sum1 + 1, 1); } else{ sum2 += a[i2]; i2 = seg::get_first(0, n, i2, n, sum2 + 1, 1); } } ll sum = 0; int i = seg::get_first(0, n, x + 1, n, a[x], 1); while(i != -1){ ll have = seg::get_sum(0, n, x + 1, i, 1); if(have >= min(a[x], a[i]) && have < min(y, a[i])){ seg::add(0, n, x + 1, i, 1, 1); if(keep) ch[chpt++] = {x, -i}; } sum += a[i]; i = seg::get_first(0, n, i + 1, n, sum + 1, 1); } sum = 0; i = seg::get_last(0, n, 0, x, a[x], 1); while(i != -1){ ll have = seg::get_sum(0, n, i + 1, x, 1); if(have >= min(a[x], a[i]) && have < min(y, a[i])){ seg::add(0, n, i + 1, x, 1, 1); if(keep) ch[chpt++] = {i, -x}; } sum += a[i]; i = seg::get_last(0, n, 0, i, sum + 1, 1); } a[x] = y; seg::upd(0, n, x, 1); return; } ll sum1 = y, sum2 = y; int i1 = seg::get_last(0, n, 0, x, y + 1, 1); int i2 = seg::get_first(0, n, x + 1, n, y + 1, 1); while(i1 != -1 && i2 != -1){ ll sum = seg::get_sum(0, n, i1 + 1, i2, 1); if(sum >= min(a[i1], a[i2]) && sum - a[x] + y < min(a[i1], a[i2])){ seg::add(0, n, i1 + 1, i2, 1, 1); if(keep) ch[chpt++] = {i1, -i2}; } if(a[i1] <= a[i2]){ sum1 += a[i1]; i1 = seg::get_last(0, n, 0, i1, sum1 + 1, 1); } else{ sum2 += a[i2]; i2 = seg::get_first(0, n, i2, n, sum2 + 1, 1); } } ll sum = 0; int i = x + 1; while(i != -1){ ll have = seg::get_sum(0, n, x + 1, i, 1); if(have < min(a[x], a[i]) && have >= min(y, a[i])){ seg::add(0, n, x + 1, i, -1, 1); if(keep) ch[chpt++] = {x, i}; } sum += a[i]; i = seg::get_first(0, n, i + 1, n, sum + 1, 1); } sum = 0; i = x - 1; while(i != -1){ ll have = seg::get_sum(0, n, i + 1, x, 1); if(have < min(a[x], a[i]) && have >= min(y, a[i])){ seg::add(0, n, i + 1, x, -1, 1); if(keep) ch[chpt++] = {i, x}; } sum += a[i]; i = seg::get_last(0, n, 0, i, sum + 1, 1); } a[x] = y; seg::upd(0, n, x, 1); return; } inline void undo(){ for(int i = chpt - 1; i >= 0; i--){ int l = ch[i].fi, r = ch[i].se; if(r == 0) continue; //cerr << "un done " << l << ' ' << r << '\n'; if(r < 0){ r *= -1; seg::add(0, n, l + 1, r, -1, 1); } else seg::add(0, n, l + 1, r, 1, 1); } chpt = 0; } inline void add(int l, int r){ ll sum = seg::get_sum(0, n, l + 1, r, 1); if(sum >= min(a[l], a[r])) return; seg::add(0, n, l + 1, r, 1, 1); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n; n += 2; seg::build(0, n, 1); a[0] = a[n - 1] = inf; av.pb(0); seg::upd(0, n, 0, 1); for(int i = 1; i < n; i++){ if(i < n - 1) cin >> a[i]; seg::upd(0, n, i, 1); while(av.size() && a[av.back()] <= a[i]){ add(av.back(), i); av.pop_back(); } if(av.size()) add(av.back(), i); av.pb(i); } int q; cin >> q; while(q--){ int ty, x, y; cin >> ty >> x >> y; if(ty == 1) update(x, y, false); else{ ll keepx = a[x - 1], keepy = a[y + 1]; chpt = 0; update(x - 1, inf, true); update(y + 1, inf, true); cout << seg::get_min(0, n, x, y + 1, 1).se << '\n'; a[y + 1] = keepy; a[x - 1] = keepx; undo(); seg::upd(0, n, x - 1, 1); seg::upd(0, n, y + 1, 1); } } } /* 5 6 4 2 2 6 3 1 3 1 2 2 5 2 1 5 2 2 4 5 6 4 2 2 6 1 2 1 3 2 1 5 1 3 1 2 2 5 2 1 5 2 2 4 3 6 4 2 1 2 1 2 10 2 3 5 10 1 3 4 9 5 2 2 1 4 1000000000 2 1 10 1 8 20 1 4 8 2 1 10 7 27 18 36 31 55 86 4 4 1 7 18 1 7 60 1 3 11 2 1 6 7 27 18 36 31 55 86 60 3 2 2 3 1 3 11 2 1 6 8 41 53 10 12 43 91 11 92 10 2 5 8 1 8 65 2 4 7 2 3 8 1 2 37 1 8 5 2 7 8 1 8 43 1 1 30 1 6 60 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...