Codefores_Hello 2023
这应该说不上一篇题解博客,而是一个反省博客
《B. MKnez's ConstructiveForces Task》

这道题我要反省的是:毫无难度,直接按照条件推式子即可,但是我将奇,偶两种情况的推导搞混掉了,寄!
《C. Least Prefix Sum》

这道题是我写的最久的,当时我是按照思维去想特殊情况,而没有用数学公式来分析,导致代码写的像答辩一样
很多细节都要考虑,十分复杂
其实这道题就是:
要Sm<=Si(1<=i<=m-1)
变化一下:Sm-Si<=0,即:S(i+1~m)<=0,(2<=i+1<=m)
于是我们就可以用贪心的方式来维护S(i+1~m)<=0
如果S(i+1~m)>0了,说明a[i+1]~a[m]有正数使得其这样,我们贪心地选这个区中最大的正数,然后反转他
在Sm<=Si(m+1<=i<=n) 同理推导与贪心
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 2 * 1e5 + 2;
typedef long long ll;
int a[N];
ll p[N];
int main()
{
int t;
cin >> t;
while (t--)
{
int n, m, ans = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
// 判断没有前段的情况:即m==1时
if (m != 1)
{
priority_queue<int, vector<int>, less<int>> heap;
// 前段操作:即对1~m-1的操作
p[m + 1] = 0;
for (int i = m; i > 1; i--)
{
p[i] = p[i + 1] + a[i];
if (a[i] > 0)
heap.push(a[i]);
while (p[i] > 0)
{
ll num = heap.top();
heap.pop();
p[i] -= 2 * num;
ans++;
}
}
}
// 后段操作:
priority_queue<int, vector<int>, greater<int>> heap2;
p[m] = 0;
for (int i = m + 1; i <= n; i++)
{
p[i] = p[i - 1] + a[i];
if (a[i] < 0)
heap2.push(a[i]);
while (p[i] < 0)
{
ll num = heap2.top();
heap2.pop();
p[i] -= 2 * num;
ans++;
}
}
cout << ans << endl;
}
return 0;
}
《D. Boris and His Amazing Haircut》

这道题其实我思路想到了,但是最后代码实现太复杂,实现不下去了,主要是因为我去代码模拟我的想法

其实简单的实现就是用堆来实现:
用堆来保存区间的数值,保证堆顶元素>新的区间元素,否则就要pop;
这个操作正好是贪心地让每一个区间在l的值固定下,让r最大,直到这个区间不能再连续为止;

1 #include <iostream>
2 #include <cstring>
3 #include <algorithm>
4 #include <map>
5 #include <stack>
6 using namespace std;
7 const int N = 2 * 1e5 + 2;
8 int t, a[N], b[N], r[N];
9 int main()
10 {
11 cin >> t;
12 while (t--)
13 {
14 int n;
15 cin >> n;
16 for (int i = 1; i <= n; i++)
17 scanf("%d", &a[i]);
18 bool flag = true;
19 for (int i = 1; i <= n; i++)
20 {
21 scanf("%d", &b[i]);
22 if (b[i] > a[i])
23 flag = false;
24 }
25 int m;
26 cin >> m;
27 map<int, int> rn;
28 for (int i = 1; i <= m; i++)
29 {
30 scanf("%d", &r[i]);
31 rn[r[i]]++;
32 }
33 if (!flag)
34 {
35 cout << "NO" << endl;
36 continue;
37 }
38 stack<int> s;
39 for (int i = 1; i <= n; i++)
40 {
41 while (s.size() && s.top() < b[i])
42 s.pop();
43 if (b[i] == a[i])
44 continue;
45 if (s.size() == 0 || s.top() > b[i])
46 {
47 if (rn[b[i]] <= 0)
48 {
49 flag = false;
50 break;
51 }
52 rn[b[i]]--;
53 s.push(b[i]);
54 }
55 }
56 if (flag)
57 cout << "YES" << endl;
58 else
59 cout << "NO" << endl;
60 }
61 return 0;
62 }
在写这道题的时候遇到了数组下标越界的情况,但是没报错,交上去真的啥问题都可能出现!

浙公网安备 33010602011771号