CF 1616D. Keep the Average High
1 /* 2 思路:把 a1 + a2 + ... + an >= x * (r - l + 1) 3 ===> a1 + a2 + ... + an - x * (r - l + 1) >= 0 4 可以等价为对于每个(ai - x) 得到新的ai,则题目变为对于任意区间[l, r], al + ... + ar >= 0. 5 6 我们先考虑: ai分布为 + - + - + - ... (ai正负交替出现) 7 8 对于 ( a1(-) a2(+) a3(-) ) 这相邻的三个数, 9 如果a1 + a2 < 0 和 a2 + a3 < 0只满足其一,则容易想到把满足等式的那个ai(-)不取. 10 如果两个都满足,则需要用到贪心的思想,我们应该不取中间的a2,因为a2不取, 11 使得我们可能可以取a1, a3; 如果是不取a1, a3则只有a2可以取. 12 13 如果上述两个等式都不成立,而 a1 + a2 + a3 < 0,则我们贪心的让a3(-)不取,这样对于后面的取与不取有意义 14 15 当然,对于ai(-)如果已经确定是不取的情况得判定 16 17 其他的就是一般的情况 - + - + + + - + + - - - 18 我们就可以知道,只需要对于ai(+)来判断左右的情况即可. 19 对于ai(-)则只需判断前面一个元素是不是负数,是不是不取来判断自己是不是不取,因为两个(-)一定是不满足题意的. 20 21 从最小的相邻的局部满足可以得到整体的满足. 22 */ 23 24 25 26 27 #include <bits/stdc++.h> 28 using namespace std; 29 30 #define ll long long 31 #define ANS cout<<"ans: "; 32 33 const int N = 1e6 + 10; 34 35 int a[N]; 36 struct node { 37 int v; 38 int w;//改数取不取 39 }; 40 int n; 41 42 inline bool check (int x, int id) 43 { 44 if(id == 0) return x - 1 >= 0; 45 else return x + 1 < n; 46 } 47 48 void solve () 49 { 50 int T; 51 cin >> T; 52 while(T --) { 53 54 cin >> n; 55 for(int i = 1; i <= n; i ++) cin >> a[i]; 56 57 int x; 58 cin >> x; 59 60 vector<node > vn; 61 for(int i = 1; i <= n; i ++) vn.push_back({a[i] - x, 1}); 62 63 int tot = 0; 64 for(int i = 0; i < n; i ++) { 65 if(vn[i].v >= 0) { 66 int l, r; 67 l = r = 0; 68 if(check(i, 0) && vn[i - 1].v < 0 && vn[i - 1].w == 1 && vn[i].v + vn[i - 1].v < 0) l = 1; 69 if(check(i, 1) && vn[i + 1].v < 0 && vn[i + 1].w == 1 && vn[i].v + vn[i + 1].v < 0) r = 1; 70 if(l + r == 2) tot ++; 71 else if(l == 1) tot ++, vn[i - 1].w = 0; 72 else if(r == 1) tot ++, vn[i + 1].w = 0; 73 else if(l + r == 0) { 74 int sum = vn[i].v; 75 if(check(i, 0) && vn[i - 1].v < 0 && vn[i - 1].w == 1) sum += vn[i - 1].v; 76 if(check(i, 1) && vn[i + 1].v < 0 && vn[i + 1].w == 1) sum += vn[i + 1].v; 77 if(sum < 0) tot ++, vn[i + 1].w = 0; 78 } 79 } else if(vn[i].v < 0 && vn[i].w == 1) { 80 if(check(i, 0) && vn[i - 1].v < 0 && vn[i - 1].w == 1) tot ++, vn[i].w = 0; 81 } 82 } 83 84 ANS; 85 cout << n - tot << endl; 86 } 87 } 88 89 int main() 90 { 91 solve(); 92 93 return 0; 94 }
1