#include "aliens.h"
#include <vector>
#include <algorithm>
using namespace std;
pair<long long, long long> solve_greedy(const vector<pair<int,int>>& segs, long long lambda) {
    long long total_cost = 0;
    long long photo_count = 0;
    int last_covered = -1;
    
    for (const auto& seg : segs) {
        int left = seg.first;
        int right = seg.second;
        
        if (right <= last_covered) continue;
        
        int actual_left = max(left, last_covered + 1);
        long long full_side = right - left + 1;
        long long full_cost = full_side * full_side;
        
        long long overlap_cost = 0;
        if (last_covered >= left && last_covered >= 0) {
            long long overlap_side = last_covered - left + 1;
            overlap_cost = overlap_side * overlap_side;
        }
        
        total_cost += full_cost - overlap_cost;
        photo_count++;
        last_covered = right;
    }
    
    return {total_cost, photo_count};
}
long long solve_wqs(const vector<pair<int,int>>& segs, int k) {
    long long lo = 0, hi = 2LL * 1000000LL * 1000000LL;
    long long best_ans = 1e18;
    
    while (lo <= hi) {
        long long lambda = (lo + hi) / 2;
        
        long long total_cost = 0;
        long long photo_count = 0;
        int last_covered = -1;
        
        for (const auto& seg : segs) {
            int left = seg.first;
            int right = seg.second;
            
            if (right <= last_covered) continue;
            
            long long full_side = right - left + 1;
            long long full_cost = full_side * full_side;
            
            long long overlap_cost = 0;
            if (last_covered >= left && last_covered >= 0) {
                long long overlap_side = last_covered - left + 1;
                overlap_cost = overlap_side * overlap_side;
            }
            
            total_cost += full_cost - overlap_cost + lambda;
            photo_count++;
            last_covered = right;
        }
        
        long long true_cost = total_cost - lambda * photo_count;
        
        if (photo_count <= k) {
            best_ans = min(best_ans, true_cost);
            hi = lambda - 1;
        } else {
            lo = lambda + 1;
        }
    }
    
    return best_ans;
}
struct Line {
    long long m, c;
    long long eval(long long x) const { return m * x + c; }
    double intersect(const Line& other) const {
        return (double)(other.c - c) / (m - other.m);
    }
};
long long solve_cht(const vector<pair<int,int>>& segs, int k) {
    int n = segs.size();
    k = min(k, n);
    if (k <= 100) {
        vector<long long> dp(n + 1, 1e18);
        dp[0] = 0;
        
        for (int j = 0; j < k; j++) {
            vector<long long> ndp(n + 1, 1e18);
            
            for (int i = j + 1; i <= n; i++) {
                for (int t = j; t < i; t++) {
                    if (dp[t] >= 1e18) continue;
                    
                    int left = segs[t].first;
                    int right = segs[i-1].second;
                    long long side = right - left + 1;
                    long long cost = side * side;
                    
                    if (t > 0) {
                        int prev_right = segs[t-1].second;
                        if (prev_right >= left) {
                            long long overlap = prev_right - left + 1;
                            cost -= overlap * overlap;
                        }
                    }
                    
                    ndp[i] = min(ndp[i], dp[t] + cost);
                }
            }
            
            dp = ndp;
        }
        
        return dp[n];
    }
    return solve_wqs(segs, k);
}
long long take_photos(int n, int m, int k, vector<int> r, vector<int> c) {
    vector<pair<int, int>> segs;
    segs.reserve(n);
    
    for (int i = 0; i < n; i++) {
        int l = min(r[i], c[i]);
        int r_val = max(r[i], c[i]);
        segs.push_back({l, r_val});
    }
    sort(segs.begin(), segs.end(), [](const auto& a, const auto& b) {
        return a.first < b.first || (a.first == b.first && a.second > b.second);
    });
    
    vector<pair<int, int>> segments;
    segments.reserve(n);
    int max_r = -1;
    
    for (const auto& seg : segs) {
        if (seg.second > max_r) {
            segments.push_back(seg);
            max_r = seg.second;
        }
    }
    
    if (segments.empty()) return 0;
    
    int s = segments.size();
    k = min(k, s);
    
    if (k >= s) {
        return solve_wqs(segments, s);
    } else if (k * (long long)s <= 4000000LL) {
        return solve_cht(segments, k);
    } else {
        return solve_wqs(segments, 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 time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |