Live2D

题解 门童

link

Description

\(n\) 个人需要接待,每个人可以被接待的时间为 \([L_i,R_i]\),你提前 \(j\) 分钟接待他的话可以产生 \(j\times p_i\) 的贡献。可以在门口和沙发之间来回,需要时间为 \(L\),待在门口或者辗转都会减少贡献,在沙发上会增加贡献。

问接待完所有人时贡献最大值。\(n\le 10^5,L_i,R_i,p_i\le 10^9\)

Solution

考场上面sb了。

可以想到的是,会辗转的时间一定在 \(L_i,R_i\) ,所以我们可以离散化,然后设 \(f_i\) 表示第 \(i\) 个时间在门口的最大贡献。

我们将需要服务的人按 \(L_i\) 排序,那么一次一定服务一段合法区间最优。然后你们 \(f_i\) 就是由 \(f_{i-1}\) 已经一段区间的 \(f_j\) 转移而来。dp 式非常好列就不写了。

然后你发现可以斜优,就做完了。

Code

#include <bits/stdc++.h>
using namespace std;

#define Int register int
#define int long long
#define MAXN 200005

template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
template <typename T> inline void chkmax (T &a,T b){a = max (a,b);}
template <typename T> inline void chkmin (T &a,T b){a = min (a,b);}

int n,m,L,x[2][2],f[MAXN],Ed[MAXN],tmp[MAXN],mpos[MAXN],mxpos[MAXN],pre1[MAXN],pre2[MAXN],Pre1[MAXN],Pre2[MAXN],minn[MAXN][21];

struct node{
	int st,ed,P;
	bool operator < (const node &p)const{return st < p.st;}
}s[MAXN];

void init (){
	for (Int i = 1;i <= n;++ i) minn[i][0] = s[i].ed;
	for (Int j = 1;(1 << j) <= n;++ j)
		for (Int i = 1;i + (1 << j) - 1 <= n;++ i)
			minn[i][j] = min (minn[i][j - 1],minn[i + (1 << j - 1)][j - 1]);
}

int query (int l,int r){
	if (l > r) return 1e18;
	int k = log2 (r - l + 1);
	return min (minn[l][k],minn[r - (1 << k) + 1][k]);
}

int head,tail,sta[MAXN];
int getb (int j){return f[j] - tmp[j] * x[1][1] - pre1[j];}
int geta (int j){return pre2[j];}
int son (int j1,int j2){return getb (j2) - getb (j1);}
int mot (int j1,int j2){return geta (j2) - geta (j1);}

signed main(){
//	freopen ("large_2.in","r",stdin);
//	freopen ("f1.out","w",stdout);
	read (n,L);
	for (Int i = 0;i < 2;++ i) for (Int j = 0;j < 2;++ j){
		read (x[i][j]);
		if (!i || !j) x[i][j] = -x[i][j];
	}
	for (Int i = 1;i <= n;++ i){
		int st,ed,p;read (st,ed,p);
		ed += st,s[i] = node{st,ed,p};
	}
	sort (s + 1,s + n + 1);
	for (Int i = 1;i <= n;++ i) Pre1[i] = Pre1[i - 1] + s[i].ed * s[i].P,Pre2[i] = Pre2[i - 1] + s[i].P;
	for (Int i = 1;i <= n;++ i) tmp[++ m] = s[i].st,tmp[++ m] = s[i].ed;
	sort (tmp + 1,tmp + m + 1),m = unique (tmp + 1,tmp + m + 1) - tmp - 1;
	memset (f,0xcf,sizeof (f)),f[0] = 0,init ();
	for (Int i = 1;i <= m;++ i){
		int tim = tmp[i];
		int l = 1,r = n,ans = 0;
		while (l <= r){
			int mid = l + r >> 1;
			if (s[mid].st <= tim) ans = mid,l = mid + 1;
			else r = mid - 1;
		}
		Ed[i] = ans,pre1[i] = Pre1[ans],pre2[i] = Pre2[ans],l = 0,r = i - 1,ans = i;
		while (l <= r){
			int mid = l + r >> 1;
			if (tim <= query (Ed[mid] + 1,Ed[i])) ans = mid,r = mid - 1;
			else l = mid + 1;
		}
		mpos[i] = ans,l = 0,r = i - 1,ans = 0;
		while (l <= r){
			int mid = l + r >> 1;
			if (tmp[i] - tmp[mid] >= 2 * L && Ed[mid] < n) ans = mid,l = mid + 1;
			else r = mid - 1;
		}
		mxpos[i] = ans;
	}
	int now = 0;sta[head = tail = 1] = 0;
	for (Int i = 1;i <= m;++ i){
		while (now < mxpos[i]){
			now ++;
			while (tail - head + 1 >= 2 && son (sta[tail - 1],sta[tail]) * mot (sta[tail],now) <= son (sta[tail],now) * mot (sta[tail - 1],sta[tail])) -- tail;
			sta[++ tail] = now;
		}
		while (head <= tail && sta[head] < mpos[i]) ++ head;
		if (mpos[i] <= mxpos[i]){
			while (head < tail && son (sta[head],sta[head + 1]) > -tmp[i] * mot (sta[head],sta[head + 1])) ++ head;
			if (head <= tail){
				int j = sta[head];
				f[i] = getb (j) + geta (j) * tmp[i] + L * (x[0][1] + x[1][0]) + (tmp[i] - 2 * L) * x[1][1] + pre1[i] - tmp[i] * pre2[i];
			}
		}
		chkmax (f[i],f[i - 1] + (tmp[i] - tmp[i - 1]) * x[0][0] + pre1[i] - pre1[i - 1] - tmp[i] * (pre2[i] - pre2[i - 1]));
	}
	int res = -1e18;
	for (Int i = 1;i <= m;++ i) if (Ed[i] == n) chkmax (res,f[i]);
	write (res),putchar ('\n');
 	return 0;
}
posted @ 2021-10-16 11:39  Dark_Romance  阅读(49)  评论(0编辑  收藏  举报