首页 > 其他分享 >P2048 [NOI2010] 超级钢琴

P2048 [NOI2010] 超级钢琴

时间:2024-08-18 15:16:29浏览次数:5  
标签:int sum len 钢琴 second NOI2010 long 端点 P2048

题意

在一个数组中选择 \(k\) 个长度为 \([l, r]\) 的序列,对每个序列求和,使每个序列的和的和最大。

思路

首先,我们可以将序列之和转化为前缀和,如果固定左端点 \(l\),那么我们只需要在 \([l + len_l, l + len_r]\) 中寻找最大的右端点,减去 \(sum[l - 1]\) 就是在长度为 \([len_l, len_r]\) 左端点为 \(l\) 的序列的最大值,这个可以用 ST 表实现。

然后,对于每次决策,我们都选择最大的那个和弦加入答案,这个我们可以用优先队列实现。假设我们选择的是以 \(l\) 为左端点,长度为 \([len_l, len_r]\) 的区间,选择的有端点为 \(r\),那么我们还需要将 \({l, len_l, r - 1}\) 和 \({l, r + 1, len_r}\) 放入优先队列,进行比较。

代码

注意开 long long。

#include <bits/stdc++.h>

using namespace std;
using i64 = long long;

const int N = 500010, K = 500010;

int n, k, l, r;
i64 a[N], sum[N], st[20][N];

void initst() {
    for (int j = 1; (1 << j) <= n; j++) {
        for (int i = 1; i + (1 << j) - 1 <= n; i++) {
            int p1 = st[j - 1][i], p2 = st[j - 1][i + (1 << j - 1)];
            if (sum[p1] < sum[p2]) st[j][i] = p2;
            else st[j][i] = p1;
        }
    }
}

int query(int l, int r) {
    int len = r - l + 1;
    int lg = __lg(len);
    int p1 = st[lg][l], p2 = st[lg][r - (1 << lg) + 1];
    if (sum[p1] < sum[p2]) return p2;
    else return p1;
}

struct node {
    int l, r_l, r_r;
};

pair<i64, int> getans(const node& a) {
    int q = query(a.r_l, a.r_r);
    i64 ans = sum[q] - sum[a.l - 1];
    return {ans, q};
}

bool operator<(const node& a, const node& b) {
    return getans(a) < getans(b);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> k >> l >> r;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        sum[i] = sum[i - 1] + a[i];
        st[0][i] = i;
    }

    initst();

    priority_queue<node> q;
    for (int i = 1; i + l - 1 <= n; i++) q.push({i, i + l - 1, min(n, i + r - 1)});
    
    i64 ans = 0;
    for (int i = 1; i <= k; i++) {
        node t = q.top();
        q.pop();

        pair<i64, int> q_t = getans(t);
        ans += q_t.first;

        if (q_t.second > t.r_l) q.push({t.l, t.r_l, q_t.second - 1});
        if (q_t.second < t.r_r) q.push({t.l, q_t.second + 1, t.r_r});
    }
    cout << ans << '\n';
    return 0;
}

标签:int,sum,len,钢琴,second,NOI2010,long,端点,P2048
From: https://www.cnblogs.com/Yuan-Jiawei/p/18365653

相关文章

  • VB.NET钢琴MIDI简谱播放器代码QZQ2024-8-7
    ImportsSystem.Runtime.InteropServicesPublicClassForm1'义WindowsAPI函数<DllImport(“winmm.dll”)>PrivateSharedFunctionmidiOutGetNumDevs()AsIntegerEndFunction<DllImport("winmm.dll")>PrivateSharedFunctionmidiOutGet......
  • D39 2-SAT P3209 [HNOI2010] 平面图判定
    视频链接:D392-SATP3209[HNOI2010]平面图判定_哔哩哔哩_bilibili   图论(十三)——平面图和对偶图_图论(十三)——平面图和对偶图-CSDN博客P3209[HNOI2010]平面图判定-洛谷|计算机科学教育新生态(luogu.com.cn)#include<iostream>#include<cstring>#incl......
  • P1447 [NOI2010] 能量采集
    题目传送容斥思想的一道好题。题目容易转化为:\[2\times\sum_{i=1}^n\sum_{j=1}^n(\gcd(i,j))\-nm.\]直接求和不好求,不妨转换为枚举\(d=\gcd(i,j)\)。那么\(i,j\)应该均为\(d\)的倍数。记\(f(i)=\left\lfloor\frac{n}{i}\right\rfloor\cdot\left\lfloor......
  • Spectrasonics Keyscape v1.5.0c + Soundsource v1.6.0c,四巨头钢琴合成器,可以试试
    SpectrasonicsKeyscapev1.5.0c+Soundsourcev1.6.0c    KEYSCAPE是一款非凡的虚拟乐器,拥有世界上最多的收集器键盘选择。从“圣杯”钢琴到令人惊叹的键盘,你甚至不知道存在,这是一个键盘手的梦想成真。经过十年的制作,这些备受欢迎的键盘都经过精心修复,然后由著名的......
  • [HNOI2010] 城市建设
    说一下大致思路,见这篇题解在往下传的过程中,会有动态边变成静态边,如于是可以递归进行reduction和contraction......
  • 【NOI2010】能量采集 题解
    【NOI2010】能量采集题解谨纪念我的第一道手推出来的莫反题。题目大意:已知\(n\),\(m\),求\(\sum\limits_{i=1}^n\sum\limits_{j=1}^m(2\cdot\gcd(i,j)-1)\)。首先变形一手:\[\sum\limits_{i=1}^n\sum\limits_{j=1}^m(2\cdot\gcd(i,j)-1)=2\sum\limits_{i=1}^n\sum\limits_{j=......
  • 洛谷题单指南-动态规划3-P3205 [HNOI2010] 合唱队
    原题链接:https://www.luogu.com.cn/problem/P3205题意解读:给定理想队形,计算初始队形的方案数。解题思路:对于给定理想队形,最后一个人插入有两种可能:从左边插入、从右边插入从左边插入,则意味着前一个数比当前数大,前一个数有可能在左边也有可能在右边从右边插入,则意味着前一个数......
  • #Trie#洛谷 6018 [Ynoi2010] Fusion tree
    题目给定一棵树,树上每个节点都有点权,需要实现三种操作,第一种是将与\(x\)相邻的所有节点点权加一,第二种是单点减小点权,第三种是查询与\(x\)相邻的所有节点点权的异或和分析相邻实际上就是父节点和子节点,不妨将其拆开考虑,需要解决单点查询单点修改的问题,考虑维护\(n\)......
  • P6018 [Ynoi2010] Fusion tree 题解
    题目链接:Fusiontree大部分人貌似用的边权01Trie,实际这题用点权01Trie类似文艺平衡树去写更方便。考虑两种常见的区间维护:线段树。使用的是父节点信息是归并了左右区间的信息,适用于不需要考虑父节点的贡献的信息。文艺平衡树。每个点就是一个信息,归并左右子树,外加当......
  • 自制小钢琴(Java)
    简易版小钢琴packagePianoGame;importjavax.swing.*;importjava.awt.*;publicclassPianoGameextendsJFrame{Buttonbutton=null;//定义两个参数,分别为宽,高publicstaticfinalintWIDTH=700;publicstaticfinalintHEIGHT=450;......