首页 > 其他分享 >「解题报告」Cover

「解题报告」Cover

时间:2023-01-18 22:02:18浏览次数:42  
标签:报告 int sum Cover son 解题 MAXN multiset st

题目大意

给定 \(m\) 个区间 \([l_i..r_i]\), 每一个区间都有一个权值 \(a_i\), 保证每个区间只有包含与不相交的关系,对于每一个 \(k=1,\ 2,\ \cdots,\ m\), 选出若干个区间,使 \([1..n]\) 中的每一个点不被超过 \(k\) 个区间覆盖,并求出最大的权值和.
\(1\le l_i\le r_i\le m,n\le300000,a_i\le10^9\)

思路

注意题目给出的一个条件:

保证每个区间只有包含与不相交的关系

所以这个区间是一个的关系。
首先建出这个树:将所有的区间按照右端点升序、左端点降序排序(或者其他方式,能建出树就可以),然后每次将区间压入一个栈中,遇到左端点大于栈顶元素的就一定满足包含关系,直接拿出即可。

接下来我们来考虑树形DP:
设 \(f_{i,j}\) 表示以 \(i\) 为根的子树中被不超过 \(j\) 段区间覆盖的最大权值和,那么不难推出以下递推式:

\[f_{i,j}=\max(\sum_{k\in son_i}f_{k,j},\ \sum_{k\in son_i}f_{k,j-1}+a_i) \]

复杂度 \(O(m^2)\), 保证会炸
我们可以尝试来优化这个DP。

考虑 \(f_{i,j}\) 的差值 \(g_{i,j}=f_{i,j}-f_{i,j-1}\), 不难发现 \(g_{i,j}\) 是单调不增的,肯定先选最优解,感性理解下
那么我们可以用一个multiset来维护这个 \(g_{i,j}\) 然后合并时启发式合并即可。
说这么简单,怎么合并???

把这个DP式子可以进行一些转换:

\[\begin{aligned} f_{i,j}&=\max(\sum_{k\in son_i}f_{k,j},\ \sum_{k\in son_i}f_{k,j-1}+a_i)\\ &=\max(\sum_{k\in son_i}\sum_{p=1}^jg_{k,p},\ \sum_{k\in son_i}\sum_{p=1}^{j-1}g_{k,p}+a_i) \end{aligned} \]

那么当 \(j\) 增加时, \(\max\) 左面的式子每次加 \(\sum_{k\in son_i}g_{k,j}\), 右面的式子每次加 \(\sum_{k\in son_i}g_{k,j-1}\), 由于 \(g_{i,j}\) 是单调不增的,那么 \(g_{k,j}\le g_{k,j-1}\), 那么 \(\sum_{k\in son_i}g_{k,j}\le \sum_{k\in son_i}g_{k,j-1}\)。
也就是说,当枚举到某一个 \(j\) 以后,右面的一定会优于左面的,假设这个分界线为 \(j\) (\(j-1\) 选左面, \(j\) 选右面), 那么我们发现:

\[\begin{aligned} g_{i,j}&=f_{i,j}-f_{i,j-1}\\ &=(\sum_{k\in son_i}\sum_{p=1}^jg_{k,p}+a_i)-\sum_{k\in son_i}\sum_{p=1}^{j}g_{k,p}\\ &=a_i \end{aligned} \]

所以我们只需要把 \(a_i\) 也扔进multiset里就可以了。
在其他情况下, \(g_{i,j}\) 就等于 \(\sum_{k\in son_i}g_{k,j}\) 或者 \(\sum_{k\in son_i}g_{k,j-1}\), 两个multiset必然是有序的, 所以直接将两个multiset对应位置相加维护就可以了。

合并时可以用一个启发式合并:其实就是将数比较少multiset的合并到数比较大的multiset,合并也很简单,两个multiset不断取begin,相加扔新multiset就可以了。

结果得到一个multiset,因为是单调递减的,直接从后往前扫一遍,把前 \(k\) 个差分加起来就是 \(f_{1,k}\) 了。

复杂度 \(O(\)我不会证\()\)

反正挺玄学的

注意

  • 可以将 \(a_i\) 取负数存进去,这样结果只需要从前往后扫, 因为我不知道为什么从后往前扫扫挂了
  • 总之能别碰迭代器就别碰,不知道怎么就挂了

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 300005;
struct Node {
    int l,r,a;
}nodes[MAXN];
int n,m;
bool cmp(const Node &a,const Node &b) {
    return a.r!=b.r?a.r<b.r:a.l>b.l;
}
int fa[MAXN],dep[MAXN],son[MAXN];
vector<int> to[MAXN];
multiset<int> dfs2(int i) {
    if (to[i].size()!=0) {
        multiset<int> s;
        multiset<int>::iterator it;
        stack<int> st;
        for(int j : to[i]) {
            multiset<int> p=dfs2(j);
            if(s.size()<p.size()) swap(s,p);
            it=s.begin();
            for(int t : p) {
                st.push(*it+t);
                s.erase(it);
                it++;
            }
            while(!st.empty()) {
                s.insert(st.top());
                st.pop();
            }
        } 
        s.insert(-nodes[i].a);
        return s;
    } else {
        multiset<int> s;
        s.insert(-nodes[i].a);
        return s;
    }
}
signed main() {
    scanf("%lld%lld", &n, &m);
    for(int i=1;i<=m;i++) scanf("%lld%lld%lld", &nodes[i].l, &nodes[i].r, &nodes[i].a);
    sort(nodes+1,nodes+1+m,cmp);
    stack<int> st;
    for(int i=1;i<=m;i++) {
        while(!st.empty() && nodes[st.top()].l>=nodes[i].l) {
            fa[st.top()]=i;
            to[i].push_back(st.top());
            st.pop();
        }
        st.push(i);
    }
    for(int i=1;i<=m;i++) if(!fa[i]) to[0].push_back(i);
    multiset<int> s=dfs2(0);
    int sum=0;
    for(int i=1;i<=m;i++) {
        if (!s.empty()) {
            sum-=*s.begin();
            s.erase(s.begin());
        }
        printf("%lld ", sum);
    }
    return 0;
}

标签:报告,int,sum,Cover,son,解题,MAXN,multiset,st
From: https://www.cnblogs.com/apjifengc/p/17060684.html

相关文章

  • 「解题报告」石子游戏
    题目大意Alice和Bob在\(n\)堆石子中取石子,这\(n\)堆石子的数量分别是\(a_i\),Alice先取,每人只能取\(1\simx\)个,假如双方都使用最优策略,求当\(x\)为\(......
  • 「解题报告」[CQOI2015]标识设计
    题目传送门首先看到题很容易能想到插头DP。但是数据范围很大,\(n,m\le30\),直接压会很爆炸。不过发现合法状态很少,因为轮廓线上最多同时只能有三个插头,所以大部分状态都......
  • 第九届产教融合发展战略国际论坛举行主场报告
    1月10日上午,第九届产教融合发展战略国际论坛主场报告通过教育部学校规划建设发展中心和驻马店市黄淮学院双会场以线上和线下相结合的形式举行。主场报告由应用技术大学(......
  • 2022中国低代码行业生态发展洞察报告
    数字经济下产品更新换代速度加快,市场需求更迭同步提速,企业不断提升软件开发效率。在此环境下,低代码的出现为企业数字化发展注入新动能,释放企业内部业务端的产品设计潜力,让技......
  • 「解题报告」ARC142D Deterministic Placing
    好?首先我们可以发现,第一步和第三步的局面必须相等,因为第二步可以反着走回第一步,如果不相等那么下一步走的方案就不唯一了。然后我们考虑走的形式,由于是一棵树,没有环,我们......
  • 洛谷普及组模拟赛 题解报告
    洛谷普及组模拟赛题解报告\[\bf{Prepared\by\InoueTakina.}\]前言:祝大家身体健康。本场比赛较为良心,经过了多次难度平衡,应该严格低于NOIP2018提高组,相信大家......
  • 洛谷P3195 玩具装箱 题解报告
    题目地址题意:如题所述。分析:斜率优化dp模板题。题目没看清就下手,自以为题面所述中i>j;原始dp式子也没设计准确。中途在错误方向上头铁时,甚至没注意到横坐标是沿......
  • 洛谷P3628 特别行动队 题解报告
    题目地址题意:把正整数序列分隔为若干区间,若单个区间的元素之和为X,则其贡献为\(aX^2+bX+c\)。求所有区间的贡献之和的最大值。分析:斜率优化dp模板题。这篇博客描述得......
  • 「解题报告」[ARC143E] Reversi
    挺弱智的题但是我不会首先从一个叶子开始考虑,如果这个叶子是白的那么就应该先选它,否则就应该先选它父亲。然后这样我们可以递归着对子树进行计算,一些子树需要先选,一些子......
  • 软件验收测试有什么注意事项?出具权威测试报告的软件检测机构安利
    软件产品在开发到发布有一个最终环节便是验收测试,软件验收测试是软件产品在部署之前的最后一个测试操作,主要是为了确保软件各方面准备就绪,可以让最终的用户将其用于执行......