結果

提出番号 2401
提出者 kya
言語 C++
提出日時 2020-07-23 11:54:16
問題名 (25)Range of Influence
結果 WA
点数 0%

テストケース

テストケース 結果 得点 実行時間 メモリ使用量
1 AC 100% 4ms 7520KB
2 WA 0% 2ms 8480KB
3 WA 0% 3ms 8032KB
4 WA 0% 3ms 7776KB
5 WA 0% 79ms 65552KB
6 WA 0% 107ms 81392KB
7 WA 0% 1344ms 817456KB
8 WA 0% 163ms 157424KB
9 WA 0% 1647ms 916912KB
10 WA 0% 1526ms 916928KB
11 WA 0% 1605ms 916912KB
12 WA 0% 2ms 8112KB
13 WA 0% 1351ms 916928KB
14 WA 0% 2ms 8112KB
15 WA 0% 1691ms 916912KB
16 AC 100% 1594ms 916928KB
17 WA 0% 2ms 7904KB
18 AC 100% 2ms 7872KB

ソースコード

#include <vector>
#include <functional>

template<class T>
struct segment_tree {
	using value_type = T;
	using F = std::function<T(T, T)>;
private : 
	int n;
	const F f;
	const value_type ie;
	std::vector<value_type> node;

public : 
	segment_tree () { }

	segment_tree (const F &f, const value_type &ie) : f(f), ie(ie) { }

	void assign (int _n) noexcept {
		n = 1;
		while (n < _n) n <<= 1;
		node.assign(2 * n, ie);
	}

	void assign (int _n, const value_type &x) noexcept {
		assign(_n);
		std::fill(node.begin() + n, node.end(), x);
		for (int i = n; i--> 0;) {
			node[i] = f(node[i << 1 | 0], node[i << 1 | 1]);
		}
	}

	template<class Iterator>
	void build (Iterator l, Iterator r) {
		assign(r - l);
		for (int i = n; l != r; i++, l++) node[i] = *l;
		for (int i = n; i--> 0;) {
			node[i] = f(node[i << 1 | 0], node[i << 1 | 1]);
		}
	}

	void set_val (int i, const value_type &x) {
		i += n;
		node[i] = x;
		for (i >>= 1; i > 0; i >>= 1) {
			node[i] = f(node[i << 1 | 0], node[i << 1 | 1]);
		}
	}

	constexpr value_type fold (int l, int r) {
		value_type vl = ie, vr = ie;
		for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
			if (l & 1) vl = f(vl, node[l++]);
			if (r & 1) vr = f(node[--r], vr);
		}
		return f(vl, vr);
	};

	constexpr const value_type& fold_all() const {
		return (node[1]);
	}

	constexpr const value_type& operator[] (int i) const {
		return node[i + n];
	}

	constexpr const value_type& at (int i) const {
		return node.at(i + n);
	}

};


#include <iostream>
#include <vector>
#include <functional>

constexpr int INF = (1 << 30);

int main() {
    int n;
    std::cin >> n;
    std::vector<int> a(n), b(n), sum(n + 1, 0);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
        sum[i + 1] = sum[i] + a[i];
    }
    for (int i = 0; i < n; i++) {
        std::cin >> b[i];
    }

    std::vector<std::vector<int>> dp(n, std::vector<int>(n, INF));
    std::vector<segment_tree<int>> segl(n, segment_tree<int>([](int a, int b) { return std::min(a, b); }, INF));
    std::vector<segment_tree<int>> segr(n, segment_tree<int>([](int a, int b) { return std::min(a, b); }, INF));
    
    std::function<void(int, int, int)> update = [&] (int l, int r, int value) -> void {
        if (r > l) return;
        if (r + 1 < n) segl[l].set_val(r + 1, value + b[r + 1]);
        if (0 < l) segr[r].set_val(l - 1, value + b[l - 1]);
    };

    for (int i = 0; i < n; i++) {
        segl[i].assign(n);
        segr[i].assign(n);
        update(i, i, b[i]);
    }

    for (int d = 1; d < n; d++) for (int l = 0; l + d < n; l++) {
        const int r = l + d;
        int low = l, high = r + 1;
        while (std::abs(high - low) > 1) {
            const int mid = ((low + high) >> 1);
            if(sum[mid] - sum[l] >= sum[r + 1] - sum[mid]) high = mid;
            else low = mid;
        }
        low++;
        dp[l][r] = std::min(segl[l].fold(low, r + 1), segr[r].fold(l, low));
        update(l, r, dp[l][r]);
    }

    std::cout << dp[0][n - 1] << '\n';

    return 0;
}