제출 #503928

#제출 시각아이디문제언어결과실행 시간메모리
503928blue모임들 (IOI18_meetings)C++17
컴파일 에러
0 ms0 KiB
#include "meetings.h"
#include <vector>
#include <algorithm>
#include <iostream>
#include <deque>
#include <cassert>
#include <cstdlib>
#include <random>
using namespace std;
 
using ll = long long;
using vll = vector<ll>;
using vi = vector<int>;
using pii = pair<int, int>;
#define sz(x) (int(x.size()))
 
const int mx = 750'000;
const ll INF = 1'000'000'000'000'000'000LL;
 
 
int N;
int Q;
 
vi H;
 
vi L, R;
vi M(mx);
vi peak_queries[mx];
 
vi HD;
 
vi lc, rc;
vi le, re;
vll ans;
 
 
 
 
 
 
 
const int stv = (1<<20);
 
 
struct segtree
{
    // int l;
    // int r;
    pii v[stv<<1];
 
    // segtree* left = NULL;
    // segtree* right = NULL;
 
 
    segtree()
    {
        ;
    }
 
    void build_segtree(int i, int l, int r, vi&Z)
    {
       // if(l > r) while(1);
       // cerr << "bld " << i << ' ' << l << ' ' << r << "\n";
        if(l == r)
        {
            v[i] = {Z[l], l};
            // cerr << "##\n";
        }
        else
        {
            int m = (l+r)/2;
            build_segtree(2*i, l, m, Z);
            build_segtree(2*i+1, m+1, r, Z);
            v[i] = max(v[2*i], v[2*i+1]);
        }
        // cerr << "bld " << i << ' ' << l << ' ' << r << " done\n";
    }
 
    void build_segtree(int L, int R, vi& Z)
    {
        // assert(L == 0);
        // assert(R == N-1);
        // build_segtree(1, 0, N-1, Z);
 
        for(int i = 0; i <= N-1; i++)
            v[stv+i] = {Z[i], i};
        for(int i = N; i < (stv); i++)
            v[stv+i] = {-1, -1};
        for(int i = stv-1; i >= 0; i--)
            v[i] = max(v[2*i], v[2*i+1]);
    }
 
    pii rangemax(int i, int l, int r, int L, int R)
    {
        if(R < l || r < L) return {-1, -1};
        else if(L <= l && r <= R) return v[i];
        else return max(rangemax(2*i, l, (l+r)/2, L, R), rangemax(2*i+1, (l+r)/2+1, r, L, R));
    }
 
    pii rangemax(int L, int R)
    {
        L += stv;
        R += stv+1;
 
        pii resv = {-1, -1};
        while(L < R)
        {
            if(L & 1)
            {
                resv = max(resv, v[L]);
                L++;
            }
 
            if(R & 1)
            {
                R--;
                resv = max(resv, v[R]);
            }
 
            L >>= 1;
            R >>= 1;
        }
 
        return resv;
 
        // return rangemax(1, 0, N-1, L, R);
    }
};
 
segtree ST;
 
vi subtree;
 
int build_tree(int l, int r)
{
    if(r < l) return -1;
    // cerr << "build tree " << l << ' ' << r << '\n';
    int m = ST.rangemax(l, r).second;
    // cerr << "m = " << m << '\n';
    // cerr << lc[m] << ' ' << rc[m] << '\n';
    lc[m] = build_tree(l, m-1);
    rc[m] = build_tree(m+1, r);
 
    if(lc[m] != -1) subtree[m] += subtree[lc[m]];
    if(rc[m] != -1) subtree[m] += subtree[rc[m]];
 
    // cerr << "build tree " << l << ' ' << r << " done\n";
 
    return m;
}
vector<int> x1, x2;
vector<ll> y1, y2;
 
 
// struct seg
// {
//     int i;
// };
 
int seg_ct = -1;
 
int new_segment(int X1, ll Y1, int X2, ll Y2)
{
    seg_ct++;
    x1.push_back(X1);
    y1.push_back(Y1);
    x2.push_back(X2);
    y2.push_back(Y2);
    // x1[seg_ct] = X1;
    // y1[seg_ct] = Y1;
    // x2[seg_ct] = X2;
    // y2[seg_ct] = Y2;
    return seg_ct;
}
 
ll get_slope(int i)
{
    if(x2[i] == x1[i]) return 0;
    else return (y2[i]-y1[i])/(x2[i]-x1[i]);
}
 
struct func
{
    ll lp = 0;
    deque<int> d;
 
    void inc(ll W)
    {
        lp += W;
    }
 
    void push_back(func& K)
    {
        for(int k: K.d)
        {
            y1[k] += K.lp - lp;
            y2[k] += K.lp - lp;
            d.push_back(k);
            // d.push_back(seg{k.x1, k.y1 + K.lp - lp, k.x2, k.y2 + K.lp - lp});
        }
    }
 
    void push_front(func& K)
    {
        while(!K.d.empty())
        {
            int k = K.d.back();
            y1[k] += K.lp - lp;
            y2[k] += K.lp - lp;
            d.push_front(k);
            K.d.pop_back();
        }
    }
 
    void front_AP(ll a, ll sl)
    {
        int xf = x1[d.front()];
        int xb = -1;
        while(!d.empty())
        {
            ll dy2 = y2[d.front()] + lp;
            int dx2 = x2[d.front()];
 
            ll dy1 = y1[d.front()] + lp;
            int dx1 = x1[d.front()];
 
 
            ll new_y2 = a + sl*(dx2 - xf);
            if(new_y2 > dy2) break;
            else if(a > dy1) break;
            else
            {
                xb = max(xb, x2[d.front()]);
                d.pop_front();
            }
        }
 
 
        if(!d.empty())
        {
            // cerr << "case X\n";
            ll dy1 = y1[d.front()] + lp;
            ll dx1 = x1[d.front()];
 
 
            ll new_y1 = a + sl*(dx1 - xf);
            if(new_y1 <= y1[d[0]] + lp)
            {
                // ll d_sl = (d[0].y2 - d[0].y1)/(d[0].x2 - d[0].x1);
                ll d_sl = get_slope(d[0]);
                int lo = x1[d[0]];
                int hi = x2[d[0]];
 
                /*
                    find highest value of lo so that a + sl*(lo - xf) <= lp + y1[d[0]] + (lo - x1[d[0]])*d_sl
                    (sl - d_sl)*lo <= lp + y1[d[0]] - x1[d[0]]*d_sl + sl*xf
                    lo = (lp + y1[d[0]] - x1[d[0]]*d_sl + sl*xf)/(sl - d_sl)
                */
 
                // while(lo != hi)
                // {
                //     int mid = (lo+hi)/2 + 1;
                //     ll mid_y = lp + y1[d[0]]+ (mid-x1[d[0]])*d_sl;
                //
                //     ll new_y = a + sl*(mid - xf);
                //
                //     if(new_y <= mid_y)
                //         lo = mid;
                //     else
                //         hi = mid-1;
                // }
                if(sl == d_sl)  lo = x1[d[0]];
                else
                {
                    lo = (lp + y1[d[0]] + (-x1[d[0]])*d_sl - a + sl*xf)/(sl - d_sl);
 
                    assert(sl >= d_sl);
                }
 
 
                xb = max(xb, lo);
 
                x1[d[0]] = lo+1;
                y1[d[0]] = y2[d[0]] - (x2[d[0]] - x1[d[0]])*d_sl;
 
            }
        }
 
 
        if(xf <= xb)
        {
            d.push_front(new_segment(xf, a - lp, xb, a+sl*(xb-xf) - lp));
        }
    }
};
 
 
 
vector<func*> F(mx);
vector<func*> F2(mx);
 
 
void dfs(int u)
{
    if(u == -1) return;
 
    le[u] = re[u] = u;
 
    if(lc[u] != -1)
    {
        dfs(lc[u]);
        subtree[u] += subtree[lc[u]];
        le[u] = le[lc[u]];
    }
    if(rc[u] != -1)
    {
        dfs(rc[u]);
        subtree[u] += subtree[rc[u]];
        re[u] = re[rc[u]];
    }
 
    for(int q: peak_queries[u])
    {
        int lo = 0;
        int hi = sz(F[rc[u]]->d) - 1;
        while(lo != hi)
        {
            int mid = (lo+hi)/2;
            if(x2[F[rc[u]]->d[mid]] < R[q])
                lo = mid+1;
            else
                hi = mid;
        }
 
        auto fr = F[rc[u]];
 
        ll right_ans = fr->lp + y1[fr->d[lo]] + get_slope(fr->d[lo])*(R[q] - x1[fr->d[lo]]);
 
 
        ans[q] = min(ans[q], ll(H[u])*(u - L[q] + 1) + right_ans);
    }
 
    ll left_ct = 1;
    if(lc[u] != -1) left_ct += subtree[lc[u]];
 
 
 
    if(rc[u] != -1)
    {
            F[rc[u]]->inc(ll(H[u])*(u - le[u] + 1));
    }
 
 
    ll dp_u;
    if(lc[u] == -1)
    {
        dp_u = H[u];
    }
    else
    {
        dp_u = H[u] + y2[F[lc[u]]->d.back()] + F[lc[u]]->lp;
    }
 
 
    func ths;
    ths.d.push_back(new_segment(u, dp_u, u, dp_u));
 
    if(rc[u] != -1)
    {
        F[rc[u]]->front_AP(dp_u + H[u], H[u]);
 
    }
 
    if(lc[u] == -1 && rc[u] == -1)
    {
        F[u]->push_back(ths);
    }
    else if(lc[u] == -1)
    {
        F[u] = F[rc[u]];
        F[u]->push_front(ths);
    }
    else if(rc[u] == -1)
    {
        F[u] = F[lc[u]];
        F[u]->push_back(ths);
    }
    else
    {
        if(rand() % 2)
        {
            F[u] = F[rc[u]];
            F[u]->push_front(ths);
            F[u]->push_front(*F[lc[u]]);
            F[lc[u]]->d.clear();
        }
        else
        {
            F[u] = F[lc[u]];
            F[u]->push_back(ths);
            F[u]->push_back(*F[rc[u]]);
            F[rc[u]]->d.clear();
        }
    }
 
    // ths->d.clear();
    ths.d.clear();
}
 
int rt;
 
 
 
 
vll minimum_costs(vi H_, vi L_, vi R_)
{
    // for(int f: L_) cerr << "le = " << f << '\n';
//PART 1: PROCESS INPUT
 
    H = H_;
    L = L_;
    R = R_;
 
    H_.clear();
    L_.clear();
    R_.clear();
 
    N = sz(H);
    Q = sz(L);
 
    // cerr << "queries: \n";
    // for(int j = 0; j < Q; j++) cerr << L_[j] << ' ' << R_[j] << '\n';
 
 
//PART 2: DISCRETISE HEIGHTS
    HD = vi(N);
    vector<pii> P;
    for(int i = 0; i < N; i++) P.push_back({H[i], i});
    sort(P.begin(), P.end());
    int ct = 0;
    for(pii p:P)
    {
        ct++;
        HD[p.second] = ct;
    }
    P.clear();
 
 
    // for(int j = 0; j < Q; j++) cerr << j << " : " << M[j] << '\n';
 
    ans = vll(Q, INF);
 
 
 
    for(int t = 0; t <= 1; t++)
    {
 
        if(t == 1)
        {
            reverse(HD.begin(), HD.end());
            reverse(H.begin(), H.end());
            for(int j = 0; j < Q; j++)
            {
                L[j] = N-1 - L[j];
                R[j] = N-1 - R[j];
                swap(L[j], R[j]);
                M[j] = N-1 - M[j];
            }
        }
 
        for(int i = 0; i < N; i++)
        {
            peak_queries[i].clear();
        }
 
        // ST = segtree(0, N-1, HD);
        ST.build_segtree(0, N-1, HD);
        for(int j = 0; j < Q; j++)
        {
            if(t == 0)
                M[j] = ST.rangemax(L[j], R[j]).second;
            if(M[j] == R[j])
            {
                ans[j] = min(ans[j], ll(H[M[j]])*(R[j] - L[j] + 1));
            }
            else
                peak_queries[M[j]].push_back(j);
        }
        // cerr << "done A\n";
 
        le = vi(N, 1'000'000'000);
        re = vi(N, -1);
        if(t == 0)
        {
            // cerr << "entered\n";
            subtree = vi(N, 1);
            lc = rc = vi(N, -1);
            rt = build_tree(0, N-1);
            // cerr << "done B\n";
            // cerr << "#\n";
        }
        else
        {
            // cerr << "entered t = " << 1 << '\n';
            rt = N-1 - rt;
            vi nwl(N), nwr(N);
            for(int i = 0; i < N; i++)
            {
                if(lc[i] == -1) nwr[i] = -1;
                else nwr[i] = N-1 - lc[i];
 
                if(rc[i] == -1) nwl[i] = -1;
                else nwl[i] = N-1 - rc[i];
            }
            reverse(subtree.begin(), subtree.end());
 
            reverse(nwr.begin(), nwr.end());
            rc = nwr;
 
            reverse(nwl.begin(), nwl.end());
            lc = nwl;
            // cerr << "done t = 1\n";
        }
 
        // cerr << "\n\n\n\n\n T = " << t << '\n';
        // for(int i = 0; i < N; i++) cerr << H[i] << ' ';
        // cerr << "\n";
        // for(int i = 0; i < N; i++) cerr << HD[i] << ' ';
        // cerr << "\n";
        // for(int i = 0; i < N; i++) cerr << lc[i] << ' ';
        // cerr << "\n";
        // for(int i = 0; i < N; i++) cerr << rc[i] << ' ';
        // cerr << "\n";
        // for(int i = 0; i < N; i++) cerr << subtree[i] << ' ';
        // cerr << "\n";
 
        // ST.clear_tree();
 
        if(t == 0)
        {
            for(int i = 0; i < N; i++) F[i] = new func;
            F2 = F;
        }
        else
        {
            F = F2;
            for(int i = 0; i < N; i++)
            {
                F[i]->lp = 0;
                F[i]->d.clear();
            }
        }
        dfs(rt);
 
        le.clear();
        re.clear();
        lc.clear();
        rc.clear();
    }
 
    return ans;
}

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

meetings.cpp:152:12: error: 'std::vector<long long int> y1' redeclared as different kind of entity
  152 | vector<ll> y1, y2;
      |            ^~
In file included from /usr/include/features.h:461,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/os_defines.h:39,
                 from /usr/include/x86_64-linux-gnu/c++/10/bits/c++config.h:518,
                 from /usr/include/c++/10/bits/stl_algobase.h:59,
                 from /usr/include/c++/10/vector:60,
                 from meetings.h:3,
                 from meetings.cpp:1:
/usr/include/x86_64-linux-gnu/bits/mathcalls.h:221:1: note: previous declaration 'double y1(double)'
  221 | __MATHCALL (y1,, (_Mdouble_));
      | ^~~~~~~~~~
meetings.cpp: In function 'int new_segment(int, ll, int, ll)':
meetings.cpp:166:8: error: request for member 'push_back' in 'y1', which is of non-class type 'double(double) noexcept'
  166 |     y1.push_back(Y1);
      |        ^~~~~~~~~
meetings.cpp: In function 'll get_slope(int)':
meetings.cpp:179:28: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  179 |     else return (y2[i]-y1[i])/(x2[i]-x1[i]);
      |                            ^
meetings.cpp:179:23: error: invalid operands of types '__gnu_cxx::__alloc_traits<std::allocator<long long int>, long long int>::value_type' {aka 'long long int'} and 'double(double) noexcept' to binary 'operator-'
  179 |     else return (y2[i]-y1[i])/(x2[i]-x1[i]);
meetings.cpp: In member function 'void func::push_back(func&)':
meetings.cpp:196:17: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  196 |             y1[k] += K.lp - lp;
      |                 ^
meetings.cpp:196:19: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  196 |             y1[k] += K.lp - lp;
      |             ~~~~~~^~~~~~~~~~~~
meetings.cpp:196:19: error: assignment of read-only location '*(y1 + ((sizetype)k))'
meetings.cpp: In member function 'void func::push_front(func&)':
meetings.cpp:208:17: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  208 |             y1[k] += K.lp - lp;
      |                 ^
meetings.cpp:208:19: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  208 |             y1[k] += K.lp - lp;
      |             ~~~~~~^~~~~~~~~~~~
meetings.cpp:208:19: error: assignment of read-only location '*(y1 + ((sizetype)k))'
meetings.cpp: In member function 'void func::front_AP(ll, ll)':
meetings.cpp:224:34: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  224 |             ll dy1 = y1[d.front()] + lp;
      |                                  ^
meetings.cpp:224:36: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  224 |             ll dy1 = y1[d.front()] + lp;
      |                      ~~~~~~~~~~~~~~^~~~
meetings.cpp:224:36: error: invalid conversion from 'double (*)(double) noexcept' to 'll' {aka 'long long int'} [-fpermissive]
meetings.cpp:225:17: warning: unused variable 'dx1' [-Wunused-variable]
  225 |             int dx1 = x1[d.front()];
      |                 ^~~
meetings.cpp:242:34: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  242 |             ll dy1 = y1[d.front()] + lp;
      |                                  ^
meetings.cpp:242:36: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  242 |             ll dy1 = y1[d.front()] + lp;
      |                      ~~~~~~~~~~~~~~^~~~
meetings.cpp:242:36: error: invalid conversion from 'double (*)(double) noexcept' to 'll' {aka 'long long int'} [-fpermissive]
meetings.cpp:247:33: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  247 |             if(new_y1 <= y1[d[0]] + lp)
      |                                 ^
meetings.cpp:247:35: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  247 |             if(new_y1 <= y1[d[0]] + lp)
      |                          ~~~~~~~~~^~~~
meetings.cpp:247:23: error: ISO C++ forbids comparison between pointer and integer [-fpermissive]
  247 |             if(new_y1 <= y1[d[0]] + lp)
      |                ~~~~~~~^~~~~~~~~~~~~~~~
meetings.cpp:275:39: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  275 |                     lo = (lp + y1[d[0]] + (-x1[d[0]])*d_sl - a + sl*xf)/(sl - d_sl);
      |                                       ^
meetings.cpp:275:30: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  275 |                     lo = (lp + y1[d[0]] + (-x1[d[0]])*d_sl - a + sl*xf)/(sl - d_sl);
      |                           ~~~^~~~~~~~~~
meetings.cpp:275:41: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  275 |                     lo = (lp + y1[d[0]] + (-x1[d[0]])*d_sl - a + sl*xf)/(sl - d_sl);
      |                           ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
meetings.cpp:275:60: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  275 |                     lo = (lp + y1[d[0]] + (-x1[d[0]])*d_sl - a + sl*xf)/(sl - d_sl);
      |                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
meetings.cpp:275:64: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  275 |                     lo = (lp + y1[d[0]] + (-x1[d[0]])*d_sl - a + sl*xf)/(sl - d_sl);
      |                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
meetings.cpp:275:72: error: invalid operands of types 'double (*)(double) noexcept' and 'll' {aka 'long long int'} to binary 'operator/'
  275 |                     lo = (lp + y1[d[0]] + (-x1[d[0]])*d_sl - a + sl*xf)/(sl - d_sl);
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
      |                                                                |            |
      |                                                                |            ll {aka long long int}
      |                                                                double (*)(double) noexcept
meetings.cpp:284:24: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  284 |                 y1[d[0]] = y2[d[0]] - (x2[d[0]] - x1[d[0]])*d_sl;
      |                        ^
meetings.cpp:284:26: error: assignment of read-only location '*(y1, (y1 + ((sizetype)((func*)this)->func::d.std::deque<int>::operator[](0))))'
  284 |                 y1[d[0]] = y2[d[0]] - (x2[d[0]] - x1[d[0]])*d_sl;
      |                 ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
meetings.cpp:252:21: warning: unused variable 'hi' [-Wunused-variable]
  252 |                 int hi = x2[d[0]];
      |                     ^~
meetings.cpp:242:16: warning: unused variable 'dy1' [-Wunused-variable]
  242 |             ll dy1 = y1[d.front()] + lp;
      |                ^~~
meetings.cpp: In function 'void dfs(int)':
meetings.cpp:337:45: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  337 |         ll right_ans = fr->lp + y1[fr->d[lo]] + get_slope(fr->d[lo])*(R[q] - x1[fr->d[lo]]);
      |                                             ^
meetings.cpp:337:31: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  337 |         ll right_ans = fr->lp + y1[fr->d[lo]] + get_slope(fr->d[lo])*(R[q] - x1[fr->d[lo]]);
      |                        ~~~~~~~^~~~~~~~~~~~~~~
meetings.cpp:337:47: warning: pointer to a function used in arithmetic [-Wpointer-arith]
  337 |         ll right_ans = fr->lp + y1[fr->d[lo]] + get_slope(fr->d[lo])*(R[q] - x1[fr->d[lo]]);
      |                        ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
meetings.cpp:337:47: error: invalid conversion from 'double (*)(double) noexcept' to 'll' {aka 'long long int'} [-fpermissive]