野鸡题手写题解整合

浴谷正在蒸蒸日上,专栏区怕是马上要倒闭了。

CF2026F

题 题。题外话:这场有点水平,E 题让我重拾了最大权闭合子图的记忆。

首先考虑没有这个可持久化(只有 \(2,3,4\) 操作)怎么做。\(0/1\) 背包问题,动态维护当前的 dp 数组 \(f_i\) 表示总体积 \(\sum p\) 不超过 \(i\) 的前提下,总价值 \(\sum t\) 的最大值,\(f\) 大小为值域 \(V=2000\)。不方便撤销的滑动窗口,自然想单调队列,但是 \(f\) 这个东西不符合单调队列的底层逻辑“更靠前且更小的元素没用”,因为每个物品的贡献不是简单的取 \(\max\)

考虑如果把滑动窗口换成栈(要求 \(\mathcal O(V)\) 将某个元素压入栈或弹栈、给出体积限制 \(p\) 查询最大价值和),就可以直接做,对栈内每个物品维护它到栈底的所有物品构成的 \(f\) 即可。回到队列,引入普及组算法——双栈模拟队列就能够把问题规约到栈上。具体地,开前后两个栈 \(L,R\),入队压入 \(R\),出队时若 \(L\) 为空则把 \(R\) 中元素全部搬到 \(L\),然后从 \(L\) 弹出。显然均摊 \(\mathcal O(1)\)

回到原问题,暴力可持久化不能接受(修改量总共 \(\Theta(qV)\),多不了 \(\log\))。这类可持久化问题在操作可逆的情况下可以建出版本依赖树离线处理,对于本题,对 \(2,3\) 操作同样新建版本。考虑逆操作,要支持 pop_backpush_front,也就是把上文队列换成双端队列。双栈模拟仍然正确(插入删除都在对应一边,删除时如果那边的栈空了就把另一个栈全倒腾过来),不过复杂度是假的(多次 push_back 然后 pop_frontpop_back 交错能卡掉)。

发现每次把整个栈转移过去有点极端了。事实上,每次只转移栈底的 \(\frac{siz}2\) 个物品即可均摊 \(\mathcal O(1)\),这是一种在国外普及度很高的神秘科技。大概证明是,把底部 \(\frac{siz}2\) 个物品和顶部 \(\frac{siz}2\) 个物品一一配对,形成一种关系 \((u,v)\),后续只有在 \(u\)\(v\) 出队时,另一个才可能继续发生栈间的转移。于是总的转移物品个数与入队次数 \(+\) 出队次数相当,整体复杂度 \(\mathcal O(qV)\)

另外一开始把 \(f_i\) 定义成了体积恰好\(i\) 导致查询变成 \(\Theta(V^2)\)。。联考前得复习下普及组算法,真不知道自己能这么唐。

#include <cstdio>
#include <vector>
#include <stack>
#include <cstring>using namespace std;void cmx(int &x,int y){if(x<y) x=y;}const int W=2327;int rbq[W];struct BMI{int p,t;};void ad(int* f,BMI x){for(int i=W-1;i>=x.p;--i) cmx(f[i],f[i-x.p]+x.t);
}namespace DS{class st{struct node{BMI x;int f[W];}tmp;public:stack<node> s;bool emp(){return s.empty();}void push(BMI x){memcpy(tmp.f,s.empty()?rbq:s.top().f,W<<2);ad(tmp.f,x);tmp.x=x;s.push(tmp);}BMI acs_tp(){BMI x=s.top().x;s.pop();return x;}}l,r,t;void adj(){bool flg=r.emp();if(flg) l.s.swap(r.s);int s=(int)r.s.size()>>1;while(s--) t.push(r.acs_tp());while(!r.emp()) l.push(r.acs_tp());while(!t.emp()) r.push(t.acs_tp());if(flg) l.s.swap(r.s);}int qry(int p){int *f=l.emp()?rbq:l.s.top().f,*g=r.emp()?rbq:r.s.top().f,res=0;for(int i=0;i<=p;++i) cmx(res,f[i]+g[p-i]);return res;}BMI acs_frt(){if(l.emp()) adj();return l.acs_tp();}void pop_bck(){if(r.emp()) adj();r.acs_tp();}
}const int N=34102;vector<int> vc[N];struct qry{int p,i;};
vector<qry> qr[N];bool del[N],ref[N];BMI w[N];int ans[N];void dfs(int u){if(del[u]) w[u]=DS::acs_frt();if(ref[u]) DS::r.push(w[u]);for(auto[p,i]:qr[u]) ans[i]=DS::qry(p);for(int v:vc[u]) dfs(v);if(ref[u]) DS::pop_bck();if(del[u]) DS::l.push(w[u]);
}int cur[N],v;int main()
{int q,V=1,qc=0;scanf("%d",&q);while(q--){int f,x;scanf("%d%d",&f,&x);switch(f){case 1:vc[cur[x]].push_back(cur[++V]=++v);break;case 2:vc[cur[x]].push_back(++v),ref[cur[x]=v]=1,scanf("%d%d",&w[v].p,&w[v].t);break;case 3:vc[cur[x]].push_back(++v),del[cur[x]=v]=1;break;case 4:int p;scanf("%d",&p);qr[cur[x]].push_back((qry){p,++qc});break;}}dfs(0);for(int i=1;i<=qc;++i) printf("%d\n",ans[i]);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/883351.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发:了解@Builder装饰器

@Builder装饰是鸿蒙UI开发中,非常重要的一个装饰器,在实际的开发中,合理且正确的使用,能够让我们的代码更加的简洁前言本文代码案例基于Api13,温馨提示:内容相对来说比较简单,如果您已掌握,略过即可。如果说一个页面中组件有很多,我们都统一写到build函数中,显而易见…

P1020 [NOIP 1999 提高组] 导弹拦截(dilworth)

这道题真的做的我鬼火冒,尤其是这个第二问要用到dilworth但是我看讲解完全不知道他们在讲什么,我看了好久才理解,一个数组至少可以由几个不增子序列覆盖就等于严格单调递增的最长子序列的长度,如果是至少可以由几个严格递减子序列覆盖就等于最长单调不减子序列的长度,然后…

Linux系统介绍

1. Linux介绍 Linux和windows一样也是一个操作系统,但是与windows不同的是,Linux是一套开放源码的代码程序、并且可以自由传播的类unix操作系统软件。 Linux系统主要被应用于服务端、嵌入式开发和个人PC桌面3大领域,一般的WEB项目都是部署在Linux操作系统上。 Linux是一个基…

Linux驱动---按键

文章简述了Input子系统架构,讲解了输入设备驱动开发流程,探讨了按键消抖方法及按键驱动开发要点,为嵌入式开发提供参考。目录一、Input子系统1.1、简介1.2、Input子系统构成1.3、input_dev结构体二、输入设备驱动开发流程2.1、分配和初始化输入设备2.2、注册设备2.3、事件上…

Android studio:flutter开发环境配置

Make Android apps | Flutter 下载flutter,并配置环境变量 右击 此电脑->属性->高级系统设置->环境变量在 用户变量 新建两个变量 变量名:FLUTTER_STORAGE_BASE_URL 变量值:https://storage.flutter-io.cn 变量名:PUB_HOSTED_URL 变量值:https://pub.flutter-io.c…

相机模型(Ⅱ) 相机标定(Camera Models 2 Camera Calibration) 总结

弱透视投影(Weak perspective projection)弱透视投影是计算机视觉和摄影测量中的一种近似投影模型。在这种投影中,假设物体距离相机足够远,使得物体上各点到相机光心的距离近似相等。 从图中可以看到,有一个光心 \(O\),物体平面上的点 \(P、Q、R\) 等通过光线投影到图像平…