Submission #1255878

#TimeUsernameProblemLanguageResultExecution timeMemory
1255878allin27xAliens (IOI16_aliens)C++20
100 / 100
111 ms16556 KiB
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define _min(x,y) x = min(x,y)

const int INF = 1e18;
const int N = 1e5+4;
int dp[N];
int sm[N];
int us[N];
const int M = 1e6+4;

struct line {
	int a=0,b=0, idx = 0;
	int f(int x) {
		return a*x + b;
	}
};

struct chtr{
    line ln;
    int l,r; 
};

int intersect(line &a, line &b){
    return (b.b-a.b) / (a.a-b.a);
}

vector<chtr> cht;

int idx = 0;

void add(line ln){
    while (cht.size()){
        cht.back().r = M-1;
        auto [ls,l,r] = cht.back();
        int x = intersect(ls, ln);
        if (x < l){
            cht.pop_back(); continue;
        }
        if (x>r) return;
        cht.back().r = x;
        cht.push_back({ln, x+1, r});
        break;
    }
    if (cht.empty()) cht.push_back({ln, 0, M-1});
}

pair<int,int> query(int pt){
    int rt = cht.size();
    if (idx >= rt) idx = rt - 1;
    while (cht[idx].r < pt) idx++;
    return {cht[idx].ln.f(pt), cht[idx].ln.idx};
}



int do_dp(vector<array<int,3>> &rgs, int lambda){
    cht.clear();
    idx = 0;
    for (int i=0; i<N; i++) dp[i] = INF; dp[0] = 0;
    for (int i=0; i<N; i++) us[i] = 0; 
    for (int i=1; i<rgs.size(); i++){
        // add new ln
        line v;     
        v.b = 0; v.a = 0;
        v.b += dp[i-1];
        v.b += (rgs[i][0] - 1) * (rgs[i][0] - 1);
        v.b -= sm[i];
        v.a += 2 * (1 - rgs[i][0]);
        v.b += lambda;
        v.idx = i;
        add(v);
        //update ans
        int area = rgs[i][1] - rgs[i][0] + 1; area *= area;
        auto [mn, idx] = query(rgs[i][1]);
        dp[i] = mn + rgs[i][1] * rgs[i][1] + sm[i] - area;
        us[i] = us[idx-1] + 1;
    }
    return us[rgs.size()-1];
}

long long take_photos(signed n, signed m, signed k, std::vector<signed> rw, std::vector<signed> cl) {
    vector<array<int,3>> rgs(n);
    for (int i=0; i<n; i++){
        int l = min(rw[i], cl[i]) + 1; int r = max(rw[i], cl[i]) + 1;
        rgs[i] = {l, r, 0};
    }
    sort(rgs.begin(), rgs.end(), [](array<int,3> &a, array<int,3> &b){
        if (a[0] < b[0]) return true; 
        if (a[0] > b[0]) return false;
        return a[1] > b[1];
    });
    int lastr = -1; vector<array<int,3>> nrgs = {{0,0,0}};
    for (int i=0; i<n; i++){
        int l = rgs[i][0]; int r = rgs[i][1];
        if (r <= lastr) continue;
        int area = (r-l+1)*(r-l+1);
        if (l <= lastr) area -= (lastr-l+1)*(lastr-l+1);
        lastr = r;
        nrgs.push_back({l, r, area});
    }
    rgs = nrgs;       
    int totarea = 0;
    for (int i=rgs.size()-1; i>=0; i--){
        int area = rgs[i][1] - rgs[i][0] + 1; area *= area;
        sm[i] = totarea + area;
        totarea += rgs[i][2];
    }

    int l=0, r = 2e15;
    while (l<r){
        int m = (l+r)/2;
        if (do_dp(rgs, m) <= k) r = m; else l = m+1;
    }
    // int ans = 1e18;
    // for (int i=0; i<=m*m+1; i++) 
    //     if (do_dp(rgs, i) <= k){
    //         ans = min(ans, sm[1] + dp[rgs.size()-1] - i * us[rgs.size()-1]);
    //     }
    //for (int i=0; i<m*m+1; i++) cout<<do_dp(rgs,i)<<' '; cout<<'\n';
    do_dp(rgs,l);
    // cout<<ans<<'\n';
    return sm[1] + dp[rgs.size()-1] - l * k; 
}

Compilation message (stderr)

aliens.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
aliens_c.h:1:9: warning: #pragma once in main file
    1 | #pragma once
      |         ^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...