梦熊十三联测 B题 图书管理

听完讲解感觉这道题也不是很难啊。

解题思路:

我们要知道我们要计算的是每个中位数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;
}
相关推荐
前端小L43 分钟前
图论专题(十九):DAG上的“关键路径”——极限规划「并行课程 III」
算法·矩阵·深度优先·图论·宽度优先
scx2013100444 分钟前
20251116 树状DP总结
算法·深度优先·图论
别动哪条鱼1 小时前
MP4转AAC转换器C++
c++·ffmpeg·音视频·aac
2301_807997381 小时前
代码随想录-day47
数据结构·c++·算法·leetcode
李日灐1 小时前
手搓简单 string 库:了解C++ 字符串底层
开发语言·c++
Elias不吃糖1 小时前
LeetCode每日一练(3)
c++·算法·leetcode
别动哪条鱼1 小时前
FFmpeg 核心数据结构关系图
数据结构·ffmpeg
小龙报1 小时前
《算法通关指南数据结构和算法篇(2)--- 链表专题》
c语言·数据结构·c++·算法·链表·学习方法·visual studio
万物挽挽2 小时前
数据结构概述
数据结构
wangwangmoon_light2 小时前
1.10 数据结构之图
数据结构