Submission #244652

#TimeUsernameProblemLanguageResultExecution timeMemory
244652YeraBigger segments (IZhO19_segments)C++17
100 / 100
483 ms52344 KiB
// In The Name Of God
//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <bitset>
#include <cmath>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <iterator>
#include <functional>
#include <unordered_set>
#include <unordered_map>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
 
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define sagyndym_seni ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
 
const ll N = 5e5+5, p1 = 911382323, p2 = 972663749, INF = 1e18;
 
inline int read(){
	char c = getchar();
	bool minus = 0;
	while (c < '0' || '9' < c){
		if(c == '-'){ minus = 1;}
		c = getchar();
		if(c == '-'){ minus = 1;}
	}
	int res = 0;
	while ('0' <= c && c <= '9') {
		res = (res << 3) + (res << 1) + c - '0';
		c = getchar();
	}
	if(minus){ res *= -1;}
	return res;
}
 
ll a[N], p[N];
int n;
pair<ll, ll> dp[N];
// {num of blocks, sum in last block}

struct node{
	ll block, own_sum, pref_sum, y;
	pair<ll, ll> maxVal;
	node *left, *right;
	node(ll bl, ll own, ll pref){
		left = nullptr; right = nullptr;
		block = bl; own_sum = own; pref_sum = pref;
		maxVal = {bl, pref};
		y = (rand() << 16) | rand();
	}
};

node *root = nullptr;

inline pair<ll, ll> get_maxVal(node *v){
	return !v ? mp(-INF, -INF) : v->maxVal;
}

inline void update(node *v){
	if(!v){ return;}
	v->maxVal = max(mp(v->block, v->pref_sum), max(get_maxVal(v->left), get_maxVal(v->right)));
}

node *merge(node *t1, node *t2){
	if(!t1){ return t2;}
	if(!t2){ return t1;}
	if(t1->y < t2->y){
		t2->left = merge(t1, t2->left);
		update(t2); return t2;
	}else{
		t1->right = merge(t1->right, t2);
		update(t1); return t1;
	}
}
//[0...k]-[k + 1...n]
pair<node*, node*> split(node *v, ll k){
	if(!v){ return {v, v};}
	ll cur_node = v->pref_sum + v->own_sum;
	if(k < cur_node){
		pair<node*, node*> temp = split(v->left, k);
		v->left = temp.s; update(v);
		return {temp.f, v};
	}else{
		pair<node*, node*> temp = split(v->right, k);
		v->right = temp.f; update(v);
		return {v, temp.s};
	}
}

pair<ll, ll> max_val(ll key){
	pair<node*, node*> temp = split(root, key);
	pair<ll, ll> ans = get_maxVal(temp.f);
	root = merge(temp.f, temp.s);
	return ans;
}

void insert(ll bl, ll own, ll pref){
	pair<node*, node*> temp = split(root, pref + own);
	root = merge(temp.f, merge(new node(bl, own, pref), temp.s));
}

int main(){
	n = read();
	for(int i = 1; i <= n; i++){
		a[i] = read();
		p[i] = a[i] + p[i - 1];
	}
	insert(0, 0, 0);
	for(int r = 1; r <= n; r++){
		pair<ll, ll> temp = max_val(p[r]);
		insert(temp.f + 1, p[r] - temp.s, p[r]);
	}
	cout<<get_maxVal(root).f;
	return 0;
}
/* TIMUS: 292220YC*/
#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...