답안 #435886

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
435886 2021-06-23T21:18:24 Z Bench0310 사탕 분배 (IOI21_candies) C++17
100 / 100
4209 ms 84228 KB
#include <bits/stdc++.h>
#include "candies.h"

using namespace std;
typedef long long ll;

const ll inf=(1ll<<60);

struct obj
{
    ll sum;
    ll mn;
    ll mn_idx;
    ll mx;
    ll mx_idx;
    obj(){sum=0;mn=inf;mx=-inf;mn_idx=mx_idx=-3;}
    obj(ll x,int idx=-3){sum=mn=mx=x;mn_idx=mx_idx=idx;}
};

obj tmerge(obj a,obj b)
{
    obj r=a;
    r.sum+=b.sum;
    if(a.sum+b.mn<r.mn)
    {
        r.mn=a.sum+b.mn;
        r.mn_idx=b.mn_idx;
    }
    if(a.sum+b.mx>r.mx)
    {
        r.mx=a.sum+b.mx;
        r.mx_idx=b.mx_idx;
    }
    return r;
}

const int N=200005;
int n,q;
vector<ll> c(N);
vector<ll> mv(N);
vector<int> queries[4*N];
vector<obj> tree(4*N);
vector<ll> res(N);

int mid(int l,int r){return (l+r)/2-((l+r)<0&&((l+r)&1));}

void add_query(int idx,int l,int r,int ql,int qr,int x)
{
    if(ql>qr) return;
    if(l==ql&&r==qr) queries[idx].push_back(x);
    else
    {
        int m=mid(l,r);
        add_query(2*idx,l,m,ql,min(qr,m),x);
        add_query(2*idx+1,m+1,r,max(ql,m+1),qr,x);
    }
}

void update(int idx,int l,int r,int pos,obj o)
{
    if(l==r) tree[idx]=o;
    else
    {
        int m=mid(l,r);
        if(pos<=m) update(2*idx,l,m,pos,o);
        else update(2*idx+1,m+1,r,pos,o);
        tree[idx]=tmerge(tree[2*idx],tree[2*idx+1]);
    }
}

bool ok(obj o,ll val){return (o.mx-o.mn)>=val;}

obj descend(int idx,int l,int r,ll val,obj req=obj())
{
    if(l==r) return tmerge(tree[idx],req);
    int m=mid(l,r);
    if(ok(tmerge(tree[2*idx+1],req),val)==1) return descend(2*idx+1,m+1,r,val,req);
    else return descend(2*idx,l,m,val,tmerge(tree[2*idx+1],req));
}

ll query(int idx,int l,int r,int ql,int qr)
{
    if(ql>qr) return 0;
    if(l==ql&&r==qr) return tree[idx].sum;
    int m=mid(l,r);
    return query(2*idx,l,m,ql,min(qr,m))+query(2*idx+1,m+1,r,max(ql,m+1),qr);
}

void solve(int idx,int l,int r)
{
    for(int x:queries[idx]) update(1,-2,q-1,x,obj(mv[x],x));
    if(l==r)
    {
        obj o=descend(1,-2,q-1,c[l]);
        if(o.mn_idx<o.mx_idx) res[l]=c[l]+query(1,-2,q-1,o.mx_idx+1,q-1);
        else res[l]=query(1,-2,q-1,o.mn_idx+1,q-1);
    }
    else
    {
        int m=mid(l,r);
        solve(2*idx,l,m);
        solve(2*idx+1,m+1,r);
    }
    for(int x:queries[idx]) update(1,-2,q-1,x,obj());
}

vector<int> distribute_candies(vector<int> nc,vector<int> nl,vector<int> nr,vector<int> nv)
{
    n=nc.size();
    for(int i=0;i<n;i++) c[i]=nc[i];
    q=nl.size();
    for(int i=0;i<q;i++)
    {
        mv[i]=nv[i];
        add_query(1,0,n-1,nl[i],nr[i],i);
    }
    update(1,-2,q-1,-2,obj(inf,-2));
    update(1,-2,q-1,-1,obj(-inf,-1));
    solve(1,0,n-1);
    vector<int> r(n);
    for(int i=0;i<n;i++) r[i]=res[i];
    return r;
}

vector<int> bf(vector<int> nc,vector<int> nl,vector<int> nr,vector<int> nv)
{
    n=nc.size();
    q=nl.size();
    vector<int> a(n);
    for(int i=0;i<q;i++)
    {
        int l=nl[i];
        int r=nr[i];
        int x=nv[i];
        for(int j=l;j<=r;j++) a[j]=clamp(a[j]+x,0,nc[j]);
    }
    return a;
}

//int main()
//{
//    mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());
//    auto rng=[&](int l,int r)->int{return uniform_int_distribution<int>(l,r)(gen);};
//    while(1)
//    {
//        n=rng(1,100);
//        q=rng(1,200);
//        vector<int> cap(n);
//        for(int i=0;i<n;i++) cap[i]=rng(1,10);
//        vector<int> l(q),r(q),v(q);
//        for(int i=0;i<q;i++)
//        {
//            l[i]=rng(0,n-1);
//            r[i]=rng(l[i],n-1);
//            v[i]=(rng(0,1)==0?-1:1)*rng(1,10);
//        }
//        vector<int> one=distribute_candies(cap,l,r,v);
//        vector<int> two=bf(cap,l,r,v);
//        if(one==two) cout << "OK" << endl;
//        else
//        {
//            cout << n << "\n";
//            for(int i=0;i<n;i++) cout << cap[i] << " \n"[i==n-1];
//            cout << q << "\n";
//            for(int i=0;i<q;i++) cout << l[i] << " " << r[i] << " " << v[i] << "\n";
//            cout << "Received: ";
//            for(int i=0;i<n;i++) cout << one[i] << " \n"[i==n-1];
//            cout << "Expected: ";
//            for(int i=0;i<n;i++) cout << two[i] << " \n"[i==n-1];
//            break;
//        }
//    }
////    int n;
////    cin >> n;
////    vector<int> nc(n);
////    for(int i=0;i<n;i++) cin >> c[i];
////    int q;
////    cin >> q;
////    vector<int> l(q),r(q),v(q);
////    for(int i=0;i<q;i++) cin >> l[i] >> r[i] >> v[i];
////    vector<int> x=distribute_candies(nc,l,r,v);
////    for(int i=0;i<n;i++) cout << x[i] << " \n"[i==n-1];
//    return 0;
//}
# 결과 실행 시간 메모리 Grader output
1 Correct 30 ms 54988 KB Output is correct
2 Correct 31 ms 55016 KB Output is correct
3 Correct 33 ms 55104 KB Output is correct
4 Correct 37 ms 55160 KB Output is correct
5 Correct 54 ms 55280 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3872 ms 84052 KB Output is correct
2 Correct 3934 ms 84172 KB Output is correct
3 Correct 3759 ms 84132 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 30 ms 55080 KB Output is correct
2 Correct 2071 ms 69720 KB Output is correct
3 Correct 166 ms 59148 KB Output is correct
4 Correct 3841 ms 84100 KB Output is correct
5 Correct 4209 ms 84172 KB Output is correct
6 Correct 3767 ms 84072 KB Output is correct
7 Correct 3380 ms 84172 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 32 ms 55072 KB Output is correct
2 Correct 37 ms 55032 KB Output is correct
3 Correct 201 ms 60928 KB Output is correct
4 Correct 122 ms 57532 KB Output is correct
5 Correct 340 ms 63028 KB Output is correct
6 Correct 333 ms 63160 KB Output is correct
7 Correct 328 ms 63028 KB Output is correct
8 Correct 328 ms 63056 KB Output is correct
9 Correct 372 ms 63080 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 30 ms 54988 KB Output is correct
2 Correct 31 ms 55016 KB Output is correct
3 Correct 33 ms 55104 KB Output is correct
4 Correct 37 ms 55160 KB Output is correct
5 Correct 54 ms 55280 KB Output is correct
6 Correct 3872 ms 84052 KB Output is correct
7 Correct 3934 ms 84172 KB Output is correct
8 Correct 3759 ms 84132 KB Output is correct
9 Correct 30 ms 55080 KB Output is correct
10 Correct 2071 ms 69720 KB Output is correct
11 Correct 166 ms 59148 KB Output is correct
12 Correct 3841 ms 84100 KB Output is correct
13 Correct 4209 ms 84172 KB Output is correct
14 Correct 3767 ms 84072 KB Output is correct
15 Correct 3380 ms 84172 KB Output is correct
16 Correct 32 ms 55072 KB Output is correct
17 Correct 37 ms 55032 KB Output is correct
18 Correct 201 ms 60928 KB Output is correct
19 Correct 122 ms 57532 KB Output is correct
20 Correct 340 ms 63028 KB Output is correct
21 Correct 333 ms 63160 KB Output is correct
22 Correct 328 ms 63028 KB Output is correct
23 Correct 328 ms 63056 KB Output is correct
24 Correct 372 ms 63080 KB Output is correct
25 Correct 32 ms 55004 KB Output is correct
26 Correct 155 ms 58028 KB Output is correct
27 Correct 2065 ms 69852 KB Output is correct
28 Correct 3933 ms 84168 KB Output is correct
29 Correct 3703 ms 83988 KB Output is correct
30 Correct 3814 ms 84148 KB Output is correct
31 Correct 3708 ms 84228 KB Output is correct
32 Correct 3760 ms 84152 KB Output is correct