Submission #836542

#TimeUsernameProblemLanguageResultExecution timeMemory
836542arnold518모임들 (IOI18_meetings)C++17
100 / 100
3072 ms407516 KiB
#include "meetings.h"
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int MAXN = 75e4;
const ll INF = 1e18;

int N, Q;
ll A[MAXN+10];
pii B[MAXN+10];
ll ans[MAXN+10], ans1[MAXN+10], ans2[MAXN+10];

struct SEG
{
	pll tree[MAXN*4+10];
	void init(int node, int tl, int tr)
	{
		if(tl==tr)
		{
			tree[node]={A[tl], tl};
			return;
		}
		int mid=tl+tr>>1;
		init(node*2, tl, mid);
		init(node*2+1, mid+1, tr);
		tree[node]=max(tree[node*2], tree[node*2+1]);
	}
	pll query(int node, int tl, int tr, int l, int r)
	{
		if(r<tl || tr<l) return pll(0, 0);
		if(l<=tl && tr<=r) return tree[node];
		int mid=tl+tr>>1;
		return max(query(node*2, tl, mid, l, r), query(node*2+1, mid+1, tr, l, r));
	}
}seg;

struct LiChao
{
	pll tree[MAXN*4+10];
	ll lazy[MAXN*4+10];
	void init(int node, int tl, int tr)
	{
		tree[node]=pll(0, INF);
		lazy[node]=0;
		if(tl==tr) return;
		int mid=tl+tr>>1;
		init(node*2, tl, mid);
		init(node*2+1, mid+1, tr);
	}
	void busy(int node, int tl, int tr)
	{
		tree[node].second+=lazy[node];
		if(tl!=tr)
		{
			lazy[node*2]+=lazy[node];
			lazy[node*2+1]+=lazy[node];
		}
		lazy[node]=0;
	}
	ll query(int node, int tl, int tr, int x)
	{
		busy(node, tl, tr);
		ll ret=tree[node].first*x+tree[node].second;
		if(tl==tr) return ret;
		int mid=tl+tr>>1;
		if(x<=mid) ret=min(ret, query(node*2, tl, mid, x));
		else ret=min(ret, query(node*2+1, mid+1, tr, x));
		return ret;
	}
	void update(int node, int tl, int tr, int l, int r, ll k)
	{
		busy(node, tl, tr);
		if(l<=tl && tr<=r)
		{
			lazy[node]+=k;
			busy(node, tl, tr);
			return;
		}
		if(r<tl || tr<l) return;
		int mid=tl+tr>>1;
		update(node*2, tl, mid, l, r, k);
		update(node*2+1, mid+1, tr, l, r, k);
	}
	void update2(int node, int tl, int tr, pll p)
	{
		busy(node, tl, tr);
		ll fl=tree[node].first*tl+tree[node].second, fr=tree[node].first*tr+tree[node].second;
		ll nfl=p.first*tl+p.second, nfr=p.first*tr+p.second;
		if(fl<=nfl && fr<=nfr) return;
		if(nfl<=fl && nfr<=fr) { tree[node]=p; return; }
		int mid=tl+tr>>1;
		update2(node*2, tl, mid, p);
		update2(node*2+1, mid+1, tr, p);
	}
	void update1(int node, int tl, int tr, int l, int r, pll p)
	{
		busy(node, tl, tr);
		if(l<=tl && tr<=r)
		{
			update2(node, tl, tr, p);
			return;
		}
		if(r<tl || tr<l) return;
		int mid=tl+tr>>1;
		update1(node*2, tl, mid, l, r, p);
		update1(node*2+1, mid+1, tr, l, r, p);
	}
}lct1, lct2;

vector<pii> LV[MAXN+10], RV[MAXN+10];

void solve(int l, int r)
{
	if(l>r) return;
	pll t=seg.query(1, 1, N, l, r);
	int mid=t.second;

	solve(l, mid-1);
	solve(mid+1, r);

	ll val;
	if(l<=mid-1) val=lct1.query(1, 1, N, mid-1)+A[mid];
	else val=A[mid];
	lct1.update1(1, 1, N, mid, mid, pll(0, val));
	lct1.update(1, 1, N, mid+1, r, A[mid]*(mid-l+1));
	lct1.update1(1, 1, N, mid+1, r, pll(A[mid], -A[mid]*mid+val));

	if(mid+1<=r) val=lct2.query(1, 1, N, mid+1)+A[mid];
	else val=A[mid];
	lct2.update1(1, 1, N, mid, mid, pll(0, val));
	lct2.update(1, 1, N, l, mid-1, A[mid]*(r-mid+1));
	lct2.update1(1, 1, N, l, mid-1, pll(-A[mid], A[mid]*mid+val));

	while(!LV[l].empty() && LV[l].back().first<=r)
	{
		int t=LV[l].back().second;
		ans1[t]=lct1.query(1, 1, N, LV[l].back().first);
		LV[l].pop_back();
	}
	while(!RV[r].empty() && RV[r].back().first>=l)
	{
		int t=RV[r].back().second;
		ans2[t]=lct2.query(1, 1, N, RV[r].back().first);
		RV[r].pop_back();
	}
	//printf("solve %d %d\n", l, r);
	//for(int i=l; i<=r; i++) printf("%lld ", lct1.query(1, 1, N, i)); printf("\n");
	//for(int i=l; i<=r; i++) printf("%lld ", lct2.query(1, 1, N, i)); printf("\n");
}

vector<ll> ret;
vector<ll> minimum_costs(vector<int> _H, vector<int> _L, vector<int> _R)
{
	N=_H.size(); Q=_L.size();
	for(int i=1; i<=N; i++) A[i]=_H[i-1];
	for(int i=1; i<=Q; i++) B[i]={_L[i-1]+1, _R[i-1]+1};

	seg.init(1, 1, N);

	for(int i=1; i<=Q; i++)
	{
		auto [l, r] = B[i];
		ans[i]=INF;
		
		int t=seg.query(1, 1, N, l, r).second;
		if(l==r) ans[i]=A[l];

		if(t+1<=r) LV[t+1].push_back({r, i});
		if(l<=t-1) RV[t-1].push_back({l, i});
	}
	for(int i=1; i<=N; i++)
	{
		sort(LV[i].begin(), LV[i].end(), greater<pii>());
		sort(RV[i].begin(), RV[i].end());
		//for(auto it : LV[i]) printf("%d %d / ", it.first, it.second); printf(" : %d\n", i);
		//for(auto it : RV[i]) printf("%d %d / ", it.first, it.second); printf(" : %d\n", i);
	}

	lct1.init(1, 1, N); lct2.init(1, 1, N);
	solve(1, N);

	for(int i=1; i<=Q; i++)
	{
		auto [l, r] = B[i];
		int t=seg.query(1, 1, N, l, r).second;
		ans[i]=min(ans[i], ans1[i]+(t-l+1)*A[t]);
		ans[i]=min(ans[i], ans2[i]+(r-t+1)*A[t]);
	}

	for(int i=1; i<=Q; i++) ret.push_back(ans[i]);
	return ret;
}

Compilation message (stderr)

meetings.cpp: In member function 'void SEG::init(int, int, int)':
meetings.cpp:27:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   27 |   int mid=tl+tr>>1;
      |           ~~^~~
meetings.cpp: In member function 'pll SEG::query(int, int, int, int, int)':
meetings.cpp:36:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   36 |   int mid=tl+tr>>1;
      |           ~~^~~
meetings.cpp: In member function 'void LiChao::init(int, int, int)':
meetings.cpp:50:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   50 |   int mid=tl+tr>>1;
      |           ~~^~~
meetings.cpp: In member function 'll LiChao::query(int, int, int, int)':
meetings.cpp:69:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   69 |   int mid=tl+tr>>1;
      |           ~~^~~
meetings.cpp: In member function 'void LiChao::update(int, int, int, int, int, ll)':
meetings.cpp:84:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   84 |   int mid=tl+tr>>1;
      |           ~~^~~
meetings.cpp: In member function 'void LiChao::update2(int, int, int, pll)':
meetings.cpp:95:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   95 |   int mid=tl+tr>>1;
      |           ~~^~~
meetings.cpp: In member function 'void LiChao::update1(int, int, int, int, int, pll)':
meetings.cpp:108:13: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  108 |   int mid=tl+tr>>1;
      |           ~~^~~
#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...