Submission #620804

# Submission time Handle Problem Language Result Execution time Memory
620804 2022-08-03T09:25:59 Z MKopchev Distributing Candies (IOI21_candies) C++17
3 / 100
5000 ms 60184 KB
#include "candies.h"
#include<bits/stdc++.h>
using namespace std;

const int nmax=2e5+42;

struct info
{
    long long sum;
    long long maxi_subarray,maxi_pref,maxi_suff;
    int id_maxi_pref;

    long long mini_subarray,mini_pref,mini_suff;
    int id_mini_pref;
};

info tree[4*nmax];

info my_merge(info LHS,info RHS)
{
    info ret;

    ret.sum=LHS.sum+RHS.sum;

    ret.maxi_pref=max(LHS.maxi_pref,LHS.sum+RHS.maxi_pref);

    if(LHS.maxi_pref>LHS.sum+RHS.maxi_pref)ret.id_maxi_pref=LHS.id_maxi_pref;
    else ret.id_maxi_pref=RHS.id_maxi_pref;

    ret.maxi_suff=max(RHS.maxi_suff,RHS.sum+LHS.maxi_suff);

    ret.maxi_subarray=max(max(LHS.maxi_subarray,RHS.maxi_subarray),LHS.maxi_suff+RHS.maxi_pref);



    ret.mini_pref=min(LHS.mini_pref,LHS.sum+RHS.mini_pref);

    if(LHS.mini_pref<LHS.sum+RHS.mini_pref)ret.id_mini_pref=LHS.id_mini_pref;
    else ret.id_mini_pref=RHS.id_mini_pref;

    ret.mini_suff=min(RHS.mini_suff,RHS.sum+LHS.mini_suff);

    ret.mini_subarray=min(min(LHS.mini_subarray,RHS.mini_subarray),LHS.mini_suff+RHS.mini_pref);

    return ret;
}

void update(int node,int l,int r,int pos,int val)
{
    if(l==r)
    {
        tree[node].sum=val;

        tree[node].maxi_subarray=max(0,val);
        tree[node].maxi_pref=tree[node].maxi_subarray;
        tree[node].maxi_suff=tree[node].maxi_subarray;

        if(tree[node].maxi_pref>0)tree[node].id_maxi_pref=l;
        else tree[node].id_maxi_pref=l-1;

        tree[node].mini_subarray=min(0,val);
        tree[node].mini_pref=tree[node].mini_subarray;
        tree[node].mini_suff=tree[node].mini_subarray;

        if(tree[node].mini_pref<0)tree[node].id_mini_pref=l;
        else tree[node].id_mini_pref=l-1;

        return;
    }

    int av=(l+r)/2;

    if(pos<=av)update(node*2,l,av,pos,val);
    else update(node*2+1,av+1,r,pos,val);

    tree[node]=my_merge(tree[node*2],tree[node*2+1]);
}

info query(int node,int l,int r,int lq,int rq)
{
    if(l==lq&&r==rq)return tree[node];

    int av=(l+r)/2;

    if(rq<=av)return query(node*2,l,av,lq,rq);
    if(av<lq)return query(node*2+1,av+1,r,lq,rq);

    return my_merge(query(node*2,l,av,lq,av),query(node*2+1,av+1,r,av+1,rq));
}

vector< pair<int,int> > updates[nmax];

int given[nmax];

std::vector<int> distribute_candies(std::vector<int> c, std::vector<int> l,
                                    std::vector<int> r, std::vector<int> v) {

    int n=c.size();

    int q=l.size();

    for(int j=0;j<q;j++)
    {
        updates[l[j]].push_back({j,v[j]});
        updates[r[j]+1].push_back({j,0});
    }

    vector<int> outp={};

    for(int i=0;i<n;i++)
    {
        for(auto w:updates[i])
        {
            given[w.first]=w.second;

            update(1,0,q-1,w.first,w.second);
        }

        int ok=q,not_ok=-1;

        while(ok-not_ok>1)
        {
            int av=(ok+not_ok)/2;

            info cur=query(1,0,q-1,av,q-1);

            if(cur.maxi_subarray>=c[i]||cur.mini_subarray<=-c[i])not_ok=av;
            else ok=av;
        }

        int cur=0;

        //cout<<"before "<<i<<" -> "<<ok<<endl;

        if(ok>0)
        {
            if(given[ok-1]<0)
            {
                cur=0;

                if(ok<q)ok=query(1,0,q-1,ok,q-1).id_mini_pref+1;
            }
            else
            {
                cur=c[i];

                if(ok<q)ok=query(1,0,q-1,ok,q-1).id_maxi_pref+1;
            }
        }

        //cout<<i<<" -> "<<ok<<" cur= "<<cur<<endl;

        for(int j=ok;j<q;j++)
        {
            cur+=given[j];

            if(cur<0)cur=0;
            else if(cur>c[i])cur=c[i];
        }

        outp.push_back(cur);
    }

    return outp;
}

/*
int main() {
    int n;
    assert(1 == scanf("%d", &n));
    std::vector<int> c(n);
    for(int i = 0; i < n; ++i) {
        assert(scanf("%d", &c[i]) == 1);
    }

    int q;
    assert(1 == scanf("%d", &q));
    std::vector<int> l(q), r(q), v(q);
    for(int i = 0; i < q; ++i) {
        assert(scanf("%d %d %d", &l[i], &r[i], &v[i]) == 3);
    }

    std::vector<int> ans = distribute_candies(c, l, r, v);

    for(int i = 0; i < n; ++i) {
        if (i > 0) {
            printf(" ");
        }
        printf("%d", ans[i]);
    }
    printf("\n");
    fclose(stdout);
    return 0;
}
*/
# Verdict Execution time Memory Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 3 ms 5012 KB Output is correct
3 Correct 5 ms 5332 KB Output is correct
4 Correct 6 ms 5404 KB Output is correct
5 Correct 12 ms 5460 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 3943 ms 57896 KB Output is correct
2 Execution timed out 5104 ms 60184 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 4 ms 5020 KB Output is correct
2 Correct 935 ms 53780 KB Output is correct
3 Correct 842 ms 10128 KB Output is correct
4 Execution timed out 5030 ms 57996 KB Time limit exceeded
5 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 3 ms 4948 KB Output is correct
3 Correct 256 ms 50888 KB Output is correct
4 Correct 344 ms 8148 KB Output is correct
5 Execution timed out 5060 ms 53068 KB Time limit exceeded
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 3 ms 5012 KB Output is correct
3 Correct 5 ms 5332 KB Output is correct
4 Correct 6 ms 5404 KB Output is correct
5 Correct 12 ms 5460 KB Output is correct
6 Correct 3943 ms 57896 KB Output is correct
7 Execution timed out 5104 ms 60184 KB Time limit exceeded
8 Halted 0 ms 0 KB -