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;
}