Problem 1

Description

Find the number of all intervals in an array with mean greater than or equal to t

Solution

sumisum_i denotes the prefix sum of the array from 1 to i,

then the mean of interval [i+1,j][i+1,j] is

sumjsumiji\frac{sum_j - sum_i}{j-i}
sumjsumijit\frac{sum_j - sum_i}{j-i} \geq t
sumjt×jsumit×isum_j - t \times j \geq sum_i - t \times i

Code 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;

const int MAXN = 1e6 + 10;
const ll MOD = 1e9 + 7;
ll n, t;
ll a[MAXN], b[MAXN], c[MAXN];
ll bit[MAXN];

ll lowbit(ll i) {
return i & (-i);
}

void add(ll i, int x) {
for (; i <= n + 1; i += lowbit(i))
bit[i] += x;
}

ll sum(ll i) {
ll ans = 0;
for (; i; i -= lowbit(i))
ans += bit[i];
return ans;
}

int main() {
cin >> n >> t;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] += a[i - 1];
}
for (int i = 1; i <= n; i++) {
b[i] = a[i] - i * t;
c[i] = b[i];
}
sort(c, c + 1 + n);
ll ans = 0;
for (int i = 0; i <= n; i++) {
ll pos = lower_bound(c, c + 1 + n, b[i]) - c + 1;
ans = (ans + sum(pos)) % MOD;
add(pos, 1);
}
cout << (ll) ans << endl;
}

Code 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <algorithm>
#include <iostream>
#define ll long long
using namespace std;

const int MAXN = 1e6 + 10;
const ll MOD = 1e9 + 7;
ll n, t, ans;
ll a[MAXN];
ll q[MAXN];

void merge_sort(int l, int r, ll *a) {
if (l >= r)
return;
int mid = l + r >> 1;
merge_sort(l, mid, a);
merge_sort(mid + 1, r, a);
int i = l, j = mid + 1, t = 0;
while (i <= mid && j <= r) {
if (a[i] > a[j]) {
q[t++] = a[j++];
ans += mid - i + 1;
ans %= MOD;
} else
q[t++] = a[i++];
}
while (i <= mid) q[t++] = a[i++];
while (j <= r) q[t++] = a[j++];
for (int i = l, j = 0; i <= r; i++, j++)
a[i] = q[j];
}

int main() {
cin >> n >> t;
for (int i = 1; i <= n; i++) {
cin >> a[i];
a[i] += a[i - 1] - t;
}
merge_sort(0, n, a);
cout << (ll) (n * (n + 1) / 2 - ans) % MOD << endl;
return 0;
}

Problem 2

Description

Maximize the median sweetness level of m desserts while staying within a budget of v.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int MAX_N = 1e5 + 10;
struct sweet {
int ness;//sweetness
int price;
} sweets[MAX_N];
bool cmp(sweet x, sweet y) { return x.ness < y.ness; }
int v, n, m;
int sum1[MAX_N], sum2[MAX_N];
int main() {
int ans = 0;
cin >> v >> n >> m;
for (int i = 1; i <= n; i++)
cin >> sweets[i].ness >> sweets[i].price;
sort(sweets + 1, sweets + 1 + n, cmp);
priority_queue<int> q1, q2;
// compute the sum of prices from the left end of the array
for (int i = 1; i <= n; i++) {
q1.push(sweets[i].price);
sum1[i] = sum1[i - 1] + sweets[i].price;
if (q1.size() > m / 2 - 1 + m % 2)
sum1[i] -= q1.top(), q1.pop();
}
// compute the sum of prices from the right end of the array
for (int i = n; i > 0; i--) {
for (int i = n; i > 0; i--) {
q2.push(sweets[i].price);
sum2[i] = sum2[i + 1] + sweets[i].price;
if (q2.size() > m / 2)
sum2[i] -= q2.top(), q2.pop();
}
if (m % 2) {
// search for the sweet with the maximum sweetness that satisfies the budget constraint
for (int i = n - m / 2; i >= m / 2 + 1; i--)
if (sum1[i - 1] + sum2[i + 1] + sweets[i].price <= v) {
cout << sweets[i].ness;
break;
}
} else {
for (int i = m / 2; i <= n - m / 2; i++) {
int l = i + 1, r = n - m / 2 + 1;
int tmp = 0;
while (l <= r) {
int mid = l + (r - l) / 2;
if (sum1[i - 1] + sum2[mid] + sweets[i].price <= v)
l = mid + 1, tmp = mid;
else
r = mid - 1;
}
if (tmp > i)
ans = max(ans, sweets[i].ness + sweets[tmp].ness);
}
cout << ans / 2 << "\n";
}
return 0;
}