梦熊十三联测 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;
}
相关推荐
美狐美颜sdk4 分钟前
美颜SDK是什么?直播/短视频美颜SDK技术详解
人工智能·算法·美颜sdk·直播美颜sdk·美颜api
DowneyJoy16 分钟前
【Unity3D补充知识点】常用数据结构分析-集合(List<T>)
数据结构·unity·c#·list
华农DrLai24 分钟前
什么是远程监督?怎么自动生成训练数据?
人工智能·算法·llm·prompt·知识图谱
计算机安禾26 分钟前
【数据结构与算法】第16篇:串(String)的定长顺序存储与朴素模式匹配
c语言·数据结构·c++·学习·算法·visual studio code·visual studio
2401_8274999927 分钟前
python核心语法01-数据存储与运算
java·数据结构·python
AI科技星34 分钟前
基于v≡c公设的理论优化方案
c语言·开发语言·算法·机器学习·数据挖掘
江不清丶35 分钟前
垃圾收集算法深度解析:从标记-清除到分代收集的演进之路
java·jvm·算法
副露のmagic37 分钟前
链表章节 leetcode 思路&实现
数据结构·leetcode·链表
·心猿意码·1 小时前
C++ 链接陷阱与底层溯源:ODR、inline 与匿名命名空间的那些坑
c++
Dr.F.Arthur1 小时前
我的算法学习笔记——链表篇
数据结构·笔记·学习·链表