Submission #1179908

#TimeUsernameProblemLanguageResultExecution timeMemory
1179908LudisseyBuilding Bridges (CEOI17_building)C++20
100 / 100
124 ms96724 KiB
#include <bits/stdc++.h>
using namespace std;
typedef pair<long long,long long> line;
#define sz(a) (int)a.size()
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define int long long
#define m real
#define q imag

int f(line a, int x){
    return a.first*x+a.second;
}

struct node {
    line l;
    node* left;
    node* right;
    int val(int x){
        return f(l,x);
    }
};
struct segtree{
    node* root;
    int N;
    void build(node* v, int l, int r){
        if(l==r){
            v->l={0,(int)1e17};
            return;
        }
        int mid=(l+r)/2;
        v->left=new node{{0,(int)1e17},NULL,NULL};
        v->right=new node{{0,(int)1e17},NULL,NULL};
        build(v->left,l,mid);
        build(v->right,mid+1,r);
    }
    
    void update(node* v, int l, int r, line ln){
        int mid=(l+r)/2;
        bool mb=v->val(mid)>f(ln,mid);
        bool lb=v->val(l)>f(ln,l);
        if(mb) swap(ln,v->l);
        if(l==r) return;
        if(lb!=mb) {
            update(v->left,l,mid,ln);
        }else {
            update(v->right,mid+1,r,ln);
        }
    }
    
    int query(node* v, int l, int r, int x){
        int mid=(l+r)/2;
        if(l==r) return v->val(x);
        int rt=0;
        if(x>mid) rt=query(v->right,mid+1,r,x);
        else rt=query(v->left,l,mid,x);
        return min(rt,v->val(x));
    }
    segtree(int n){
        root=new node{{0,(int)1e17},NULL,NULL};
        N=n;
        build(root,0,N-1);
    }
    int query(int x){
        return query(root,0,N-1,x);
    }
    void update(line l){
        update(root,0,N-1,l);
    }
};

signed main() {
    ios_base::sync_with_stdio(false); cin.tie(nullptr);
    int n; cin >> n;
    vector<int> h(n);
    vector<int> w(n);
    for (int i = 0; i < n; i++) cin >> h[i];
    for (int i = 0; i < n; i++) cin >> w[i];
    int sm=0;
    for (int i = 0; i < n; i++) sm+=w[i];
    vector<int> dp(n,1e17);
    dp[0]=-w[0];
    segtree seg(1e6+1);
    seg.update({-2*h[0],h[0]*h[0]+dp[0]});
    for (int i = 1; i < n; i++)
    {
        dp[i]=seg.query(h[i])+h[i]*h[i]-w[i];
        seg.update({-2*h[i],h[i]*h[i]+dp[i]});
    }
    cout << dp[n-1]+sm << "\n";
    
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...