This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,fma,bmi,bmi2,sse4.2,popcnt,lzcnt")
#include <bits/stdc++.h>
#define taskname ""
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define int long long
#define ll long long
#define ld long double
#define pb push_back
#define ff first
#define ss second
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vii vector<pii>
using namespace std;
const int mxN = 250000 + 5;
const int mod = 1e9 + 7;
const ll oo = 1e18;
struct node {
ll sum_plus, sum_minus, idx;
pll pref_min;
node() {
sum_plus = sum_minus = idx = 0;
pref_min = {0, mod};
}
node operator + (const node &o) {
node res;
res.sum_plus = sum_plus + o.sum_plus;
res.sum_minus = sum_minus + o.sum_minus;
res.pref_min = min(pref_min, {sum_plus - sum_minus + o.pref_min.ff, o.pref_min.ss});
return res;
}
} segtree[4 * mxN];
int n, m, q, ans[mxN];
vector<vector<ll>> query;
vi query_time[mxN], all_query;
vii actual_query[mxN];
void update(int l, int r, int idx, int pos, int val) {
if(l == r) {
if(val > 0) {
if(query[pos][0] == 1) segtree[idx].sum_plus = query[pos][2];
else if(query[pos][0] == 2) segtree[idx].sum_minus = query[pos][1];
segtree[idx].pref_min = {min(segtree[idx].sum_plus, -segtree[idx].sum_minus), pos};
segtree[idx].idx = pos;
}
else {
segtree[idx] = node();
}
return;
}
int mid = (l + r) >> 1;
if(pos <= mid) update(l, mid, idx << 1, pos, val);
else update(mid + 1, r, idx << 1 | 1, pos, val);
segtree[idx] = segtree[idx << 1] + segtree[idx << 1 | 1];
}
node get(int l, int r, int idx, int u, int v) {
if(v < u) return node();
if(u <= l && r <= v) {
return segtree[idx];
}
int mid = (l + r) >> 1;
if(v <= mid) return get(l, mid, idx << 1, u, v);
else if(mid + 1 <= u) return get(mid + 1, r, idx << 1 | 1, u, v);
else return get(l, mid, idx << 1, u, v) + get(mid + 1, r, idx << 1 | 1, u, v);
}
int huutuannguvailon(int cur_l, int cur_r, ll k) {
int l = 1, r = q, idx = 1;
while(l < r) {
int mid = (l + r) >> 1;
if(k > segtree[idx << 1].sum_plus) {
k -= segtree[idx << 1].sum_plus;
idx = idx << 1 | 1, l = mid + 1;
}
else {
idx <<= 1, r = mid;
}
}
return query[l][1];
}
void solve() {
cin >> n >> m >> q;
query.pb({});
for(int i = 1; i <= q; ++i) {
int type; cin >> type;
vector<ll> tmp = {type};
if(type == 1) {
int l, r; cin >> l >> r;
query_time[l].emplace_back(i);
query_time[r + 1].emplace_back(-i);
ll k, c; cin >> c >> k;
tmp.emplace_back(c);
tmp.emplace_back(k);
}
else if(type == 2) {
int l, r; cin >> l >> r;
query_time[l].emplace_back(i);
query_time[r + 1].emplace_back(-i);
ll k; cin >> k; tmp.emplace_back(k);
}
else {
all_query.emplace_back(i);
ll cur, k; cin >> cur >> k;
actual_query[cur].emplace_back(i, k);
}
query.pb(tmp);
}
for(int i = 1; i <= n; ++i) {
for(int &val : query_time[i]) {
if(val > 0) update(1, q, 1, val, 1);
else update(1, q, 1, -val, -1);
}
int cope = segtree[1].pref_min.ss;
if(cope == mod) {
for(auto &[idx, k] : actual_query[i])
ans[idx] = 0;
continue;
}
for(auto &[idx, k] : actual_query[i]) {
auto cur = get(1, q, 1, 1, idx);
cope = cur.pref_min.ss;
if(cope == mod || cope == idx) {
ans[idx] = 0;
continue;
}
auto cur1 = get(1, q, 1, cope, idx);
if(query[cope][0] == 2)
cur1.sum_minus -= query[cope][1];
ll actual_k = k + cur1.sum_minus;
if(actual_k > cur1.sum_plus) {
ans[idx] = 0;
continue;
}
ans[idx] = huutuannguvailon(cope, idx, actual_k + cur.sum_plus - cur1.sum_plus);
}
}
for(int &idx : all_query) cout << ans[idx] << endl;
}
signed main() {
#ifndef CDuongg
if(fopen(taskname".inp", "r"))
assert(freopen(taskname".inp", "r", stdin)), assert(freopen(taskname".out", "w", stdout));
#else
freopen("bai3.inp", "r", stdin);
freopen("bai3.out", "w", stdout);
auto start = chrono::high_resolution_clock::now();
#endif
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1; //cin >> t;
while(t--) solve();
#ifdef CDuongg
auto end = chrono::high_resolution_clock::now();
// cout << "\n"; for(int i = 1; i <= 100; ++i) cout << '=';
// cout << "\nExecution time: " << chrono::duration_cast<chrono::milliseconds> (end - start).count() << "[ms]" << endl;
#endif
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |