답안 #620852

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

            //cout<<"av= "<<av<<" cur= "<<cur.maxi_pref<<" "<<cur.mini_pref<<" "<<cur.maxi_subarray<<" "<<cur.mini_subarray<<endl;

            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;
            }
        }
        else
        {
            ok=query(1,0,q-1,0,q-1).id_mini_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 4 ms 4992 KB Output is correct
2 Correct 3 ms 4948 KB Output is correct
3 Correct 5 ms 5444 KB Output is correct
4 Correct 7 ms 5332 KB Output is correct
5 Correct 10 ms 5460 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 995 ms 57212 KB Output is correct
2 Correct 1044 ms 57120 KB Output is correct
3 Correct 1112 ms 57252 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4948 KB Output is correct
2 Correct 461 ms 54984 KB Output is correct
3 Correct 400 ms 11184 KB Output is correct
4 Correct 1400 ms 61812 KB Output is correct
5 Correct 1134 ms 63728 KB Output is correct
6 Correct 836 ms 63900 KB Output is correct
7 Correct 801 ms 63272 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4948 KB Output is correct
2 Correct 3 ms 4948 KB Output is correct
3 Correct 156 ms 50660 KB Output is correct
4 Correct 196 ms 8144 KB Output is correct
5 Correct 669 ms 54112 KB Output is correct
6 Correct 543 ms 54564 KB Output is correct
7 Correct 375 ms 54312 KB Output is correct
8 Correct 648 ms 54400 KB Output is correct
9 Correct 1058 ms 55304 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 4992 KB Output is correct
2 Correct 3 ms 4948 KB Output is correct
3 Correct 5 ms 5444 KB Output is correct
4 Correct 7 ms 5332 KB Output is correct
5 Correct 10 ms 5460 KB Output is correct
6 Correct 995 ms 57212 KB Output is correct
7 Correct 1044 ms 57120 KB Output is correct
8 Correct 1112 ms 57252 KB Output is correct
9 Correct 3 ms 4948 KB Output is correct
10 Correct 461 ms 54984 KB Output is correct
11 Correct 400 ms 11184 KB Output is correct
12 Correct 1400 ms 61812 KB Output is correct
13 Correct 1134 ms 63728 KB Output is correct
14 Correct 836 ms 63900 KB Output is correct
15 Correct 801 ms 63272 KB Output is correct
16 Correct 2 ms 4948 KB Output is correct
17 Correct 3 ms 4948 KB Output is correct
18 Correct 156 ms 50660 KB Output is correct
19 Correct 196 ms 8144 KB Output is correct
20 Correct 669 ms 54112 KB Output is correct
21 Correct 543 ms 54564 KB Output is correct
22 Correct 375 ms 54312 KB Output is correct
23 Correct 648 ms 54400 KB Output is correct
24 Correct 1058 ms 55304 KB Output is correct
25 Correct 3 ms 4948 KB Output is correct
26 Correct 231 ms 9320 KB Output is correct
27 Correct 448 ms 54424 KB Output is correct
28 Correct 1106 ms 61704 KB Output is correct
29 Correct 978 ms 62284 KB Output is correct
30 Correct 896 ms 62232 KB Output is correct
31 Correct 857 ms 62500 KB Output is correct
32 Correct 838 ms 62592 KB Output is correct