听完讲解感觉这道题也不是很难啊。
解题思路:
我们要知道我们要计算的是每个中位数pi的贡献。
对于pj>pi,令aj=1,对于pj<pi,令aj=-1,问题可以转变为有多个区间[l,r]满足
从i往左扫描并累加和,使用一个数组标记每种sj的取值个数
类似从i往右扫描并累加和,并询问取值为-tj的s数量
这种做法时间复杂度为O(n^2)。
代码如下:
cpp
#include <bits/stdc++.h>
using namespace std;
int n, p[10005];
long long tmp[20010];
int main() {
freopen("book.in", "r", stdin);
freopen("book.out", "w", stdout);
cin.tie(0)->sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++) cin >> p[i];
long long ans = 0;
for (int i = 1; i <= n; i++) {
long long sws = 0;
for (int j = 0; j <= 20004; j++) tmp[j] = 0;
int plc = 0;
for (int j = 1; j <= n; j++)
if (p[j] == i)
plc = j;
int sum = 10002;
for (int j = plc; j >= 1; j--) {
if (p[j] < i)
sum--;
if (p[j] > i)
sum++;
tmp[sum] += j;
}
sum = 10002;
for (int j = plc; j <= n; j++) {
if (p[j] < i)
sum--;
if (p[j] > i)
sum++;
sws += tmp[20004 - sum] * j;
}
ans += sws * i;
}
cout << ans;
return 0;
}
此题暴力做法能打到50分,剩下的点会TLE掉
cpp
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 10;
int n;
int a[maxn], b[maxn];
int val[maxn][maxn];
long long ans;
void f(int l, int r) {
if (l == r) {
val[l][r] = a[l];
return;
}
int mid = (l + r) / 2;
f(l, mid);
f(mid + 1, r);
int c[maxn];
int p = l, q = mid + 1, k = 0;
memcpy(c, b, sizeof(b));
while (p <= mid || q <= r) {
if (p > mid) {
c[l + (k++)] = b[q];
q++;
} else if (q > r) {
c[l + (k++)] = b[p];
p++;
} else {
if (b[p] <= b[q]) {
c[l + (k++)] = b[p];
p++;
} else {
c[l + (k++)] = b[q];
q++;
}
}
}
for (int i = l; i <= r; i++) {
b[i] = c[i];
}
val[l][r] = b[mid];
}
int main() {
freopen("book.in", "r", stdin);
freopen("book.out", "w", stdout);
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
for (int l = n / 2 * 2; l >= 0; l -= 2) {
for (int i = 1; i + l <= n; i++) {
int j = i + l;
memcpy(b, a, sizeof(a));
if (val[i][j] == 0)
f(i, j);
ans += 1LL * i * j * val[i][j];
}
}
printf("%lld", ans);
return 0;
}