제출 #1299978

#제출 시각아이디문제언어결과실행 시간메모리
1299978trandangquang푸드 코트 (JOI21_foodcourt)C++20
100 / 100
420 ms47968 KiB
#include<bits/stdc++.h>
using namespace std;

#define foru(i,a,b) for(int i=(a); i<=(b); ++i)
#define ford(i,a,b) for(int i=(a); i>=(b); --i)
#define rep(i,a) for(int i=0; i<(a); ++i)
#define sz(a) (int)(a).size()
#define all(a) (a).begin(),(a).end()
#define bit(s,i) (((s)>>(i))&1)
#define ii pair<int,int>
#define vi vector<int>
#define vii vector<ii>
#define fi first
#define se second
#define ll long long
#define eb emplace_back
#define pb push_back
#define __builtin_popcount __builtin_popcountll
#define _ << " " <<

template <class X, class Y> bool maxi(X &x, Y y){return x<y?x=y,true:false;}
template <class X, class Y> bool mini(X &x, Y y){return x>y?x=y,true:false;}

const int N=252525;

int n,m,q;
int tq[N],lq[N],rq[N],aq[N]; ll bq[N];

void input(){
    cin>>n>>m>>q;
    foru(i,1,q){
        cin>>tq[i];
        if(tq[i]==1){
            cin>>lq[i]>>rq[i]>>aq[i]>>bq[i];
        } else if(tq[i]==2){
            cin>>lq[i]>>rq[i]>>bq[i];
        } else if(tq[i]==3){
            cin>>aq[i]>>bq[i];
        } else{
            assert(0);
        }
    }
}

#define lc id<<1
#define rc id<<1|1

struct{
    ll st[N<<2];
    void upd(int u, int v, ll val, int id=1, int l=1, int r=n){
        if(u>r||v<l)return;
        if(u<=l&&r<=v){
            st[id]+=val;
            return;
        }
        int mid=(l+r)>>1;
        upd(u,v,val,lc,l,mid);
        upd(u,v,val,rc,mid+1,r);
    }
    ll get(int x){
        int id=1, l=1, r=n; ll res=0;
        while(true){
            res+=st[id];
            if(l==r) break;

            int mid=(l+r)>>1;
            if(x<=mid) id=lc, r=mid;
            else id=rc, l=mid+1;
        }
        return res;
    }
} t1;

struct{
    ll del[N<<2],add[N<<2]; /// del before add

    void appDel(int id, ll val){
        ll t=min(val,add[id]);
        add[id]-=t;
        del[id]+=val-t;
    }
    void appAdd(int id, ll val){
        add[id]+=val;
    }
    void down(int id){
        if(del[id]>0){
            appDel(lc,del[id]);
            appDel(rc,del[id]);
            del[id]=0;
        }
        if(add[id]>0){
            appAdd(lc,add[id]);
            appAdd(rc,add[id]);
            add[id]=0;
        }
    }
    void updDel(int u, int v, ll val, int id=1, int l=1, int r=n){
        if(u>r||v<l)return;
        if(u<=l&&r<=v){
            appDel(id,val);
            return;
        }
        down(id);
        int mid=(l+r)>>1;
        updDel(u,v,val,lc,l,mid);
        updDel(u,v,val,rc,mid+1,r);
    }
    void updAdd(int u, int v, ll val, int id=1, int l=1, int r=n){
        if(u>r||v<l)return;
        if(u<=l&&r<=v){
            appAdd(id,val);
            return;
        }
        down(id);
        int mid=(l+r)>>1;
        updAdd(u,v,val,lc,l,mid);
        updAdd(u,v,val,rc,mid+1,r);
    }
    ll get(int x){
        int id=1, l=1, r=n;
        while(true){
            if(l==r) break;
            down(id);
            int mid=(l+r)>>1;
            if(x<=mid) id=lc, r=mid;
            else id=rc, l=mid+1;
        }
        return add[id];
    }
} t2;

ll actDel[N];
void findActualDel(){ /// maintain two segment trees (one for current and one for just-add)
    foru(i,1,q){
        if(tq[i]==1){
            t1.upd(lq[i],rq[i],bq[i]);
            t2.updAdd(lq[i],rq[i],bq[i]);
        } else if(tq[i]==2){
            t2.updDel(lq[i],rq[i],bq[i]);
        } else if(tq[i]==3){
            actDel[i]=t1.get(aq[i])-t2.get(aq[i]);
//            cout<<i _ actDel[i]<<'\n';
        } else{
            assert(0);
        }
    }
}

///update point, get interval
struct{
    ll st[N<<2];
    void upd(int x, ll val){
        int id=1, l=1, r=q;
        while(true){
            st[id]+=val;
            if(l==r) break;

            int mid=(l+r)>>1;
            if(x<=mid) id=lc, r=mid;
            else id=rc, l=mid+1;
        }
    }
    int walk(ll k){
        int id=1, l=1, r=q;
        while(true){
            if(l==r) break;

            int mid=(l+r)>>1;
            if(k>st[lc]){
                k-=st[lc];
                id=rc, l=mid+1;
            } else{
                id=lc, r=mid;
            }
        }
        if(st[id]<k) return -1; /// if k > total
        return l; /// position of query
    }
} t3;

int ans[N];
vector<pair<int,ll>> upd[N],que[N];

void findAnswer(){
    foru(i,1,q){
        if(tq[i]==1){
            upd[lq[i]].eb(i,bq[i]);
            upd[rq[i]+1].eb(i,-bq[i]);
        } else if(tq[i]==2){
            /// do nothing
        } else if(tq[i]==3){
            que[aq[i]].eb(i,bq[i]+actDel[i]);
        } else{
            assert(0);
        }
    }

    foru(i,1,n){
        for(auto [pos,val]:upd[i]){
            t3.upd(pos,val);
        }
        for(auto [id,k]:que[i]){
            int tmp=t3.walk(k);
            if(tmp==-1) ans[id]=0;
            else ans[id]=tmp<=id ? aq[tmp] : 0;
        }
    }

    foru(i,1,q) if(tq[i]==3) cout<<ans[i]<<'\n';
}

void solve(){
    input();
    findActualDel();
    findAnswer();
}

int32_t main(){
    #define task "test"
    if(fopen(task".inp", "r")){
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }
    cin.tie(0)->sync_with_stdio(0);

    int tc=1; //cin>>tc;
    foru(i,1,tc){
        solve();
    }
}

컴파일 시 표준 에러 (stderr) 메시지

foodcourt.cpp: In function 'int32_t main()':
foodcourt.cpp:221:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  221 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
foodcourt.cpp:222:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  222 |         freopen(task".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...