답안 #620841

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
620841 2022-08-03T09:38:27 Z MKopchev 사탕 분배 (IOI21_candies) C++17
8 / 100
1042 ms 61224 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));
}

void build(int node,int l,int r)
{
    tree[node].id_maxi_pref=l;
    tree[node].id_mini_pref=l;

    if(l==r)return;

    int av=(l+r)/2;

    build(node*2,l,av);
    build(node*2+1,av+1,r);
}

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();

    build(1,0,q-1);

    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;
            }
        }

        /*
        for(int j=0;j<q;j++)cout<<given[j]<<" ";cout<<endl;

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

        cout<<"---"<<endl;
        */

        if(ok<q)cur+=query(1,0,q-1,ok,q-1).sum;

        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;
}
*/
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Incorrect 3 ms 4948 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 875 ms 58224 KB Output is correct
2 Correct 1010 ms 61224 KB Output is correct
3 Correct 1042 ms 61172 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 3 ms 4948 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4948 KB Output is correct
2 Correct 3 ms 4948 KB Output is correct
3 Incorrect 163 ms 50956 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Incorrect 3 ms 4948 KB Output isn't correct
3 Halted 0 ms 0 KB -