(淼)大家快来改T2,只用两个for循环(雾)

今天T2只用两个for循环就能切,怎么没人来改(雾)

#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
using ll = long long;
using poly = vector<ll>;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll a[N];
poly merge(const poly& a, const poly& b, bool zero){
	poly c(a.size() + b.size() - 1);
	c[0] = a[0] + b[0];
	merge(a.begin() + 1, a.end(), b.begin() + 1, b.end(), c.begin() + 1, greater<ll>());
	if(zero) c.insert(c.begin(), 0);
	return c;
}
poly max(poly a, poly b){
	poly c(max(a.size(), b.size()), -INF);
	partial_sum(a.begin(), a.end(), a.begin());
	partial_sum(b.begin(), b.end(), b.begin());
	for(int i = 0; i < c.size(); ++i){
		if(i < a.size()) c[i] = max(c[i], a[i]);
		if(i < b.size()) c[i] = max(c[i], b[i]);
	}
	adjacent_difference(c.begin(), c.end(), c.begin());
	return c;
}
array<poly, 4> solve(int l, int r){
	if(l == r) return {poly{a[l]}, poly{-a[l]}, poly{0}, poly{0}};
	int mid = (l + r) >> 1;
	array<poly, 4> lret = solve(l, mid), rret = solve(mid + 1, r), ret;
	ret[0] = max(merge(lret[0], rret[3], 0), merge(lret[2], rret[0], 0));
	ret[1] = max(merge(lret[1], rret[2], 0), merge(lret[3], rret[1], 0));
	ret[2] = max(merge(lret[2], rret[2], 0), merge(lret[0], rret[1], 1));
	ret[3] = max(merge(lret[3], rret[3], 0), merge(lret[1], rret[0], 1));
	return ret;
}
// ret  :  +O, -O , +E, -E
int n;
int main(){
    freopen("jia.in", "r", stdin);
    freopen("jia.out", "w", stdout);
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n;
	for_each(a + 1, a + 1 + n,[&](auto& x){cin >> x;});
	auto ans = solve(1, n);
	partial_sum(ans[0].begin(), ans[0].end(), ans[0].begin());
	partial_sum(ans[2].begin(), ans[2].end(), ans[2].begin());
	for(int i = 1; i <= n; ++i) cout << ans[i & 1 ? 0 : 2][i / 2] <<" ";
	return 0;
}
posted @ 2023-01-10 19:46  CDsidi  阅读(41)  评论(2编辑  收藏  举报