제출 #659752

#제출 시각아이디문제언어결과실행 시간메모리
659752JokerFav푸드 코트 (JOI21_foodcourt)C++17
100 / 100
482 ms46576 KiB
//https://oj.uz/problem/view/JOI21_foodcourt
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define pb push_back
#define int long long
int const nmax = 250007;
int ans[nmax];
int n, m, q;
vector <int> v[nmax];
vector<pair <int, int>> f[nmax];
int C[nmax], K[nmax];
ll s[nmax * 4], cnt[nmax * 4], lazy[nmax * 4];
ll tmp, val;
bool vs[nmax];
void downs(int node)
{
    if(lazy[node] == 0) return;
    s[node << 1] += lazy[node];
    s[node << 1 | 1] += lazy[node];
    lazy[node << 1] += lazy[node];
    lazy[node << 1 | 1] += lazy[node];
    lazy[node] = 0;
}
void updates(int node, int l, int r, int x)
{
    if(l >= x)
    {
        s[node] += K[x];
        lazy[node] += K[x];
        return;
    }
    int mid = (l + r) >> 1;
    downs(node);
    if(x <= mid) updates(node << 1, l, mid, x);
    updates(node << 1 | 1, mid + 1, r, x);
    s[node] = min(s[node << 1], s[node << 1 | 1]);
}
void updatecnt(int node, int l, int r, int x)
{
    if(l == r)
    {
        cnt[node] += K[x];
        return;
    }
    int mid = (l + r) >> 1;
    if(x <= mid) updatecnt(node << 1, l, mid, x);
    else updatecnt(node << 1 | 1, mid + 1, r, x);
    cnt[node] = cnt[node << 1] + cnt[node << 1 | 1];
}
void gets(int node, int l, int r, int x)
{
    if(l == r)
    {
        tmp = s[node];
        return;
    }
    int mid = (l + r) >> 1;
    downs(node);
    if(x <= mid) gets(node << 1, l, mid, x);
    else
    {
        val = min(val, s[node << 1]);
        gets(node << 1 | 1, mid + 1, r, x);
    }
}
void climb(int node, int l, int r, int x, int y)
{
    int mid = (l + r) >> 1;
    if(r <= x)
    {
        if(cnt[node] + y <= tmp)
        {
            tmp -= cnt[node];
            return;
        }
        if(l == r)
        {
            val = l;
            return;
        }
        if(cnt[node << 1 | 1] + y <= tmp)
        {
            tmp -= cnt[node << 1 | 1];
            climb(node << 1, l, mid, x, y);
        }
        else climb(node << 1 | 1, mid + 1, r, x, y);
        return;
    }
    if(x <= mid) climb(node << 1, l, mid, x, y);
    else
    {
        climb(node << 1 | 1, mid + 1, r, x, y);
        if(!val) climb(node << 1, l, mid, x, y);
    }
}
void deal(int x)
{
    updates(1, 1, q, x);
    if(C[x]) updatecnt(1, 1, q, x);
    K[x] = -K[x];
}
int getans(int x, int y)
{
    tmp = val = 0;
    gets(1, 1, q, x);
    if(tmp - val < y) return 0;
    tmp -= val;
    val = 0;
    climb(1, 1, q, x, y);
    return C[val];
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> n >> m >> q;
    for(int i = 1; i <= q; ++i)
    {
        int type, x, y;
        cin >> type >> x >> y;
        if(type == 1)
        {
            cin >> C[i] >> K[i];
            v[x].pb(i); v[y + 1].pb(i);
        }
        if(type == 2)
        {
            cin >> K[i]; K[i] = -K[i];
            v[x].pb(i); v[y + 1].pb(i);
        }
        if(type == 3)
        {
            f[x].pb({i, y});
            vs[i] = true;
        }
    }
    for(int i = 1; i <= n; ++i)
    {
        for(int j: v[i]) deal(j);
        for(auto z: f[i])
            ans[z.fi] = getans(z.fi, z.se);
    }
    for(int i = 1; i <= q; ++i)
        if(vs[i])
            cout << ans[i] << '\n';
    return 0;
}
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...