Submission #1332378

#TimeUsernameProblemLanguageResultExecution timeMemory
1332378PlayVoltzConstellation 3 (JOI20_constellation3)C++20
100 / 100
519 ms114820 KiB
#include <cstdio>
#include <stdio.h>
#include <stdbool.h>
#include <iostream>
#include <map>
#include <vector>
#include <climits>
#include <stack>
#include <string>
#include <queue>
#include <algorithm>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <cmath>
#include <cctype>
#include <bitset>
#include <iomanip>
#include <cstring>
#include <numeric>
#include <cassert>
#include <random>
#include <chrono>
#include <fstream> 
using namespace std;

#define int long long
#define mp make_pair
#define pii pair<int, int>
#define fi first
#define se second
#define pb push_back

struct node{
	int s, e, m, val;
	node *l, *r;
	
	node(int S, int E){
		s = S, e = E, m = (s+e)/2;
		val=0;
		if (s!=e){
			l = new node(s, m);
			r = new node(m+1, e);
		}
	}
	void up(int ind, int nv){
		if (s==e)val=nv;
		else{
			if (ind<=m)l->up(ind, nv);
			else r->up(ind, nv);
			val = l->val+r->val;
		}
	}
	int query(int left, int right){
		if (s==left && e==right)return val;
		if (right<=m)return l->query(left, right);
		else if (left>m)return r->query(left, right);
		else return l->query(left, m)+r->query(m+1, right);
	}
}*st;

int counter=0;
vector<int> dp, depth, in, out, sz, head, par;
vector<vector<int> > graph, twok;
vector<vector<pii> > got;

void dfs(int node, int p, int d){
	depth[node]=d;
	par[node]=p;
	twok[node][0]=p;
	for (int i=1; i<20; ++i)twok[node][i]=twok[twok[node][i-1]][i-1];;
	if (graph[node].size()>1&&graph[node][0]==p)swap(graph[node][0], graph[node][1]);
	for (auto &num:graph[node]){
		dfs(num, node, d+1);
		sz[node]+=sz[num];
		if (sz[num]>sz[graph[node][0]])swap(num, graph[node][0]);
	}
}

void dfs2(int node){
	in[node]=++counter;
	for (auto num:graph[node]){
		if (num==graph[node][0])head[num]=head[node];
		else head[num]=num;
		dfs2(num);
	}
	out[node]=counter;
}

int hldquery(int a, int b){
	int res=0;
	while (head[a]!=head[b]){
		if (depth[head[a]]<depth[head[b]])swap(a, b);
		res+=st->query(in[head[a]], in[a]);
		a=par[head[a]];
	}
	if (in[a]<in[b])swap(a, b);
	return res+st->query(in[b], in[a]);
}

void dfs3(int node){
	int sum=0;
	for (auto num:graph[node])dfs3(num), sum+=dp[num];
	dp[node]=sum;
	for (auto c:got[node])dp[node]=max(dp[node], c.se+hldquery(c.fi, node)+sum);
	st->up(in[node], sum-dp[node]);
}

int32_t main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n, m, sum=0, a, b, c;
	cin>>n;
	vector<int> vect(n+1);
	twok.resize(n+1, vector<int>(20));
	dp.resize(n+1, LLONG_MIN/2);
	par.resize(n+1);
	depth.resize(n+1);
	in.resize(n+1);
	out.resize(n+1);
	head.resize(n+1);
	sz.resize(n+1, 1);
	graph.resize(n+1);
	got.resize(n+1);
	set<int> s;
	for (int i=1; i<=n; ++i)cin>>vect[i], s.insert(i);
	stack<int> sst;
	for (int i=1; i<=n; ++i){
		int p=-1;
		while (sst.size()&&vect[sst.top()]<=vect[i])p=sst.top(), sst.pop();
		if (p!=-1)graph[i].pb(p), s.erase(p);
		sst.push(i);
	}
	while (sst.size())sst.pop();
	for (int i=n; i>=1; --i){
		int p=-1;
		while (sst.size()&&vect[sst.top()]<vect[i])p=sst.top(), sst.pop();
		if (p!=-1)graph[i].pb(p), s.erase(p);
		sst.push(i);
	}
	st = new node(1, n);
	dfs(*s.begin(), *s.begin(), 0);
	head[*s.begin()]=*s.begin();
	dfs2(*s.begin());
	cin>>m;
	while (m--){
		cin>>a>>b>>c;
		sum+=c;
		int f=a;
		for (int i=19; i>=0; --i)if (vect[twok[f][i]]<b)f=twok[f][i];
		got[f].pb(mp(a, c));
	}
	dfs3(*s.begin());
	cout<<sum-dp[*s.begin()];
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...