답안 #476973

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
476973 2021-09-29T14:53:44 Z Tien_Noob Building Bridges (CEOI17_building) C++17
30 / 100
42 ms 2880 KB
//Make CSP great again
//You're as beautiful as the day I lost you
#include <bits/stdc++.h>
#define TASK "BUILDING"
using namespace std;
///Source : USACO Guilde - Advanced - LineContainer
struct CHT
{
    struct Frac
    {
        long long u, v;
        Frac(long long a, long long b)
        {
            u = a;
            v = b;
        }
        bool operator < (const Frac other) const
        {
            long long a = u * other.v - v * other.u, b = v * other.v;
            {
                if (a < 0 && b > 0 || a > 0 && b < 0)
                {
                    return true;
                }
                return false;
            }
        }
        bool operator <= (const Frac other) const
        {
            long long a = u * other.v - v * other.u, b = v * other.v;
            {
                if (a < 0 && b > 0 || a > 0 && b < 0 || a == 0)
                {
                    return true;
                }
                return false;
            }
        }
    };
    struct Line
    {
        bool type;
        Frac x;
        long long m, c;
        bool operator < (const Line other) const
        {
            if (type || other.type)
            {
                return x < other.x;
            }
            return m > other.m;
        }
    };
    set<Line> cht;
    Frac Intersect(set<Line>::iterator l1, set<Line>::iterator l2)
    {
        return Frac((l1->c - l2->c), (l2->m - l1->m));
    }
    bool has_prev(set<Line>::iterator it)
    {
        return it != cht.begin();
    }
    bool has_next(set<Line>::iterator it)
    {
        return it != cht.end() && next(it) != cht.end();
    }
    void Cal(set<Line>::iterator it)
    {
        if (has_prev(it))
        {
            Line ha = *it;
            ha.x = Intersect(prev(it), it);
            cht.insert(cht.erase(it), ha);
        }
    }
    bool bad(set<Line>::iterator it)
    {
        if (has_next(it) && next(it)->c <= it->c)
        {
            return true;
        }
        return has_prev(it) && has_next(it) && Intersect(prev(it), next(it)) <= Intersect(prev(it), it);
    }
    void add_line(long long m, long long c)
    {
        set<Line>:: iterator it;
        it = cht.lower_bound({0, Frac(0, 1), m, c});
        if (it != cht.end() && it->m == m)
        {
            if (it->c <= c)
            {
                return ;
            }
            cht.erase(it);
        }
        it = cht.insert({0, Frac(0, 1), m, c}).first;
        if (bad(it))
        {
            cht.erase(it);
        }
        else
        {
            while (has_prev(it) && bad(prev(it)))
            {
                cht.erase(prev(it));
            }
            while (has_next(it) && bad(next(it)))
            {
                cht.erase(next(it));
            }
            if (has_next(it))
            {
                Cal(next(it));
            }
            Cal(it);
        }
    }
    long long Get(long long h)
    {
        Line l = *prev(cht.upper_bound({1, Frac(h, 1), 0, 0}));
        return l.m * h + l.c;
    }
};
CHT cht;
const int N = 1e5;
int w[N + 1], h[N + 1], n;
long long dp[N + 1], s = 0;
void read()
{
    cin >> n;
    for (int i = 1; i <= n; ++ i)
    {
        cin >> h[i];
    }
    for (int i = 1; i <= n; ++ i)
    {
        cin >> w[i];
        s += w[i];
    }
}
void solve()
{
    dp[1] = -w[1];
	for (int i = 2; i <= n; i++)
    {
		cht.add_line(-2 * h[i - 1], dp[i - 1] + h[i - 1] * h[i - 1]);
		dp[i] = cht.Get(h[i]) - w[i] + h[i] * h[i];
	}
    cout << s + dp[n];
}
int main()
{
   ios_base::sync_with_stdio(false);
   cin.tie(nullptr);
   if (fopen(TASK".INP", "r"))
   {
      freopen(TASK".INP", "r", stdin);
      freopen(TASK".OUT", "w", stdout);
   }
   int t = 1;
   bool typetest = false;
   if (typetest)
   {
      cin >> t;
   }
   for (int __ = 1; __ <= t; ++ __)
   {
      read();
      solve();
   }
}

Compilation message

building.cpp: In member function 'bool CHT::Frac::operator<(CHT::Frac) const':
building.cpp:21:27: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   21 |                 if (a < 0 && b > 0 || a > 0 && b < 0)
      |                     ~~~~~~^~~~~~~~
building.cpp: In member function 'bool CHT::Frac::operator<=(CHT::Frac) const':
building.cpp:32:27: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
   32 |                 if (a < 0 && b > 0 || a > 0 && b < 0 || a == 0)
      |                     ~~~~~~^~~~~~~~
building.cpp: In function 'int main()':
building.cpp:157:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  157 |       freopen(TASK".INP", "r", stdin);
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
building.cpp:158:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  158 |       freopen(TASK".OUT", "w", stdout);
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 316 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
3 Correct 1 ms 204 KB Output is correct
4 Correct 2 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 42 ms 2880 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 316 KB Output is correct
2 Correct 1 ms 332 KB Output is correct
3 Correct 1 ms 204 KB Output is correct
4 Correct 2 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
6 Incorrect 42 ms 2880 KB Output isn't correct
7 Halted 0 ms 0 KB -