Codeforces Round 892 (Div. 2)
C:
题意:
找出一个n的全排列使得\((\sum_{i = 1}^{i = n}{p_i * i})\) - \((max_{j = 1}^{j = n}{p_j * j})\) 最大
思路:
因为想让大的数字不被浪费掉,所以就把它和次小的数反转一下 ==> 选一段后缀反转暴力枚举一下
inline void solve()
{
int n; cin >> n;
LL ans = -INF;
for (int i = 1; i <= n; i++)
{
LL sum = 0, maxx = -INF;
for (int j = 1; j < i; j++)
{
sum += j * j;
maxx = max((LL)(j * j), maxx);
}
for (int j = i; j <= n; j++)
{
sum += j * (n - (j - i));
maxx = max((LL)(j * (n - (j - i))), maxx);
}
ans = max(ans, sum - maxx);
}
cout << ans << endl;
}
D:
题意:
给你只包含四个数的元组[l, r, a, b] 对于区间[l, r]而言区间[a, b]一定是它的子区间,如果当前你位于区间[l, r]之间,那么你可以使用传送门到达[a, b]的任意点,给你q个询问每次给你一个初始位置问你最远可以到哪
思路:
因为我们只能使用传送门行动所以[l, r, a, b]对我们来说只有[l, b]是有用的,所以先把所有的[l, b]区间合并,然后对每个查询查找一下这个数位在哪个区间里面,那它最远就是到这个区间的右端点
inline void solve()
{
int n; cin >> n;
std::vector<std::array<int, 2>> seg(n);
for (int i = 0; i < n; i++)
{
int l, a, b ,r; cin >> l >> r >> a >> b;
seg.push_back({l, b});
}
sort(seg.begin(), seg.end());
vector<array<int, 2>> a;
for (auto [l, r] : seg)
{
if (!a.empty() && l <= a.back()[1])
{
a.back()[1] = max(r, a.back()[1]);
}
else
{
a.push_back({l, r});
}
}
int q; cin >> q;
while (q--)
{
int x; cin >> x;
int l = 0, r = a.size() - 1;
while (l < r)
{
int mid = (l + r + 1) / 2;
if (x >= a[mid][0]) l = mid;
else r = mid - 1;
}
if (x >= a[l][0])
{
cout << max(x, a[l][1]) << " \n"[q == 0];
}
else cout << x << " \n"[q == 0];
}
}

浙公网安备 33010602011771号