1952. 金发姑娘和 N 头牛

题目链接

1952. 金发姑娘和 N 头牛

你可能听过关于金发姑娘和三只熊的经典故事。

然而,鲜为人知的是,金发姑娘最终成了一个农民。

在她的农场中,她的牛棚里有 \(N\) 头奶牛。

不幸的是,她的奶牛对温度相当敏感。

对于奶牛 \(i\),使其感到舒适的温度为 \(A_i…B_i\)

如果金发姑娘将牛棚的恒温器的温度 \(T\) 设置为 \(T<A_i\),奶牛就会觉得冷,并会产出 \(X\) 单位的牛奶。

如果她将恒温器的温度 \(T\) 设置在 \(A_i≤T≤B_i\),奶牛就会感到舒适,并会产出 \(Y\) 单位的牛奶。

如果她将恒温器的温度 \(T\) 设置为 \(T>B_i\),奶牛就会觉得热,并会产出 \(Z\) 单位的牛奶。

正如所期望的那样,\(Y\) 的值始终大于 \(X\)\(Z\)

给定 \(X,Y,Z\) 以及每头奶牛感到舒适的温度范围,请计算通过合理设定恒温器温度,金发姑娘可获得的最大产奶量。

恒温器温度可设置为任何整数。

输入格式

第一行包含四个整数 \(N,X,Y,Z\)

接下来 \(N\) 行,每行包含两个整数 \(A_i\)\(B_i\)

输出格式

输出可获得的最大产奶量。

数据范围

\(1≤N≤20000\),
\(0≤X,Y,Z≤1000\),
\(0≤A_i≤B_i≤10^9\)

输入样例:

4 7 9 6
5 8
3 4
13 20
7 10

输出样例:

31

样例解释

金发姑娘可以将恒温器温度设置为 \(7\)\(8\),这样会让奶牛 \(1\)\(4\) 感到舒适,奶牛 \(2\) 感到热,奶牛 \(3\) 感到冷。

共可获得 \(31\) 单位牛奶。

解题思路

差分,离散化

不妨将每一个温度区间看作三个区间,左区间上每个数加上 \(x\),中间区间加上 \(y\),右区间加上 \(z\),则问题转化为在所有之中选取权值最大的数,显然可用差分,注意需要加上左右边界,这样比较好处理,另外由于数据范围过大,还应该离散化处理

  • 时间复杂度:\(O(nlogn)\)

代码

// Problem: 金发姑娘和 N 头牛
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/1954/
// Memory Limit: 64 MB
// Time Limit: 1000 ms

// %%%Skyqwq
#include <bits/stdc++.h>

#define pb push_back
#define fi first
#define se second
#define mp make_pair
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }

template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=2e4+5,inf=0x3f3f3f3f;
int n,x,y,z;
pair<int,int> a[N];
int b[2*N];
vector<int> xs;
int main()
{
	scanf("%d%d%d%d",&n,&x,&y,&z);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i].fi,&a[i].se);
		xs.push_back(a[i].fi);
		xs.push_back(a[i].se);
	}
	xs.push_back(inf),xs.push_back(-inf);
	sort(xs.begin(),xs.end());
	xs.erase(unique(xs.begin(),xs.end()),xs.end());
	int m=xs.size();
	int res=0,sum=0;
	for(int i=1;i<=n;i++)
	{
		int pos1=lower_bound(xs.begin(),xs.end(),a[i].fi)-xs.begin();
		int pos2=lower_bound(xs.begin(),xs.end(),a[i].se)-xs.begin();
		b[0]+=x,b[pos1]-=x;
		b[pos1]+=y,b[pos2+1]-=y;
		b[pos2+1]+=z,b[m-1]-=z;
	}
	for(int i=0;i<m;i++)
		sum+=b[i],res=max(res,sum);
	printf("%d",res);
	
	return 0;
}
posted @ 2022-01-29 12:02  zyy2001  阅读(60)  评论(0编辑  收藏  举报