梦熊十三联测 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;
}
相关推荐
liuhuapeng03042 分钟前
GetMapping自动截取List<String>字符
数据结构·windows·list
Croa-vo3 分钟前
Citadel SDE 面试复盘:直面硬核算法与思维挑战的双重压力
算法·面试·职场和发展
仰泳的熊猫15 分钟前
1013 Battle Over Cities
数据结构·c++·算法·pat考试
渡我白衣1 小时前
字符串的陷阱与艺术——std::string全解析
网络·c++·人工智能·自然语言处理·智能路由器·信息与通信·caffe
吃不饱的得可可1 小时前
C++17常用新特性
开发语言·c++
_OP_CHEN1 小时前
算法基础篇:(七)基础算法之二分算法 —— 从 “猜数字” 到 “解难题” 的高效思维
c++·算法·蓝桥杯·二分查找·acm·二分答案·二分算法
一匹电信狗1 小时前
【C++11】Lambda表达式+新的类功能
服务器·c++·算法·leetcode·小程序·stl·visual studio
在等晚安么1 小时前
力扣面试150题打卡
算法·leetcode·面试
煤球王子2 小时前
学而时习之:C++中的枚举
c++
AI科技星2 小时前
宇宙膨胀速度的光速极限:基于张祥前统一场论的第一性原理推导与观测验证
数据结构·人工智能·经验分享·python·算法·计算机视觉