当前位置: 首页 > ds >正文

Codeforces Round 987 (Div. 2)

ABC 略

D

预处理出每个位置的前缀最大和后缀最小。从后向前枚举,如果一个数无法后移,那么答案就是最大前缀,否则答案要不是前缀最大,要不就是这个数先移到前缀最大位置再移到能移到的最大的位置此处的答案。用线段树维护

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int N=5e5+10;
int T,n,a[N],pre[N],suf[N],ans[N];
struct tree{int l,r,maxx;
}t[N*4];
void init()
{
}
void build(int p,int l,int r)
{t[p].l=l,t[p].r=r;t[p].maxx=0;if(l==r) return ;int mid=(l+r)/2;build(p*2,l,mid);build(p*2+1,mid+1,r);
}
void add(int p,int x,int k)
{if(t[p].l==t[p].r) {t[p].maxx=max(t[p].maxx,k); return ;}int mid=(t[p].l+t[p].r)/2;if(x<=mid) add(p*2,x,k);if(x>mid) add(p*2+1,x,k);t[p].maxx=max(t[p*2].maxx,t[p*2+1].maxx);
}
int ask(int p,int l,int r)
{if(t[p].l>=l&&t[p].r<=r) return t[p].maxx;int mid=(t[p].l+t[p].r)/2;int val=0;if(l<=mid) val=ask(p*2,l,r);if(r>mid) val=max(val,ask(p*2+1,l,r));return val;
}
void solve()
{cin>>n;init();for(int i=1;i<=n;i++)cin>>a[i];build(1,1,n);for(int i=1;i<=n;i++)pre[i]=max(pre[i-1],a[i]);suf[n]=a[n];for(int i=n-1;i>=1;i--)suf[i]=min(suf[i+1],a[i]);ans[n]=pre[n];add(1,a[n],n);for(int i=n-1;i>=1;i--){if(pre[i]<suf[i+1]){add(1,a[i],i);ans[i]=pre[i];continue;}ans[i]=max(ans[ask(1,1,pre[i]-1)],pre[i]);add(1,a[i],i);}for(int i=1;i<=n;i++)cout<<ans[i]<<" ";cout<<endl;
}
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie();cin>>T;while(T--) solve();
}

E

设f[x]表示x的子树的最小层数。首先明确删点操作只能增加一个层中点的个数,不能增加层数。一个点如果他的孩子数量<=2,那么f[x]就是它的儿子中最大f+1。当它的孩子>2时,在原二叉树中,父亲和所有儿子不再是全父子关系,存在儿子在原图中是父亲孙子的情况。下面我们将执行一个还原操作,将这个节点的子树还原为二叉树,此时它的孩子全部还原完成且知道还原完的层数。我们每次还原删去的父亲节点的f值就是它的两个孩子的f值中大的那个+1。相当于我们每次取两个孩子合成一个新的孩子,这个孩子的值为之前两个孩子的最大值+1,然后循环操作,直到就剩两个孩子为止,此时这两个孩子合成的就是原父亲节点。贪心每次选最小的两个合成即可,用优先队列维护。

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
const int N=1e6+10;
int T,n,f[N];
vector<int> e[N];
void init()
{for(int i=1;i<=n;i++)e[i].clear();
}
void dfs(int x)
{priority_queue<int> q;for(int y : e[x]){dfs(y);q.emplace(-f[y]);}if(q.empty()) {f[x]=1; return ;}if(q.size()==1) {f[x]=-q.top()+1; return ;}while(q.size()>2){q.pop();int u=-q.top();q.pop();q.emplace(-(u+1));}q.pop();int u=-q.top();q.pop();f[x]=u+1;
}
void solve()
{cin>>n;init();for(int i=2;i<=n;i++){int x;cin>>x;e[x].emplace_back(i);}dfs(1);cout<<f[1]-1<<endl;
}
signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie();cin>>T;while(T--) solve();
}

http://www.xdnf.cn/news/17319.html

相关文章:

  • 数据结构—队列和栈
  • 问题定位排查手记1 | 从Windows端快速检查连接状态
  • Java面试宝典:类加载器分层设计与核心机制解析
  • PyCharm vs. VSCode 到底哪个更好用
  • C++、STL面试题总结(二)
  • 图论(邻接表)DFS
  • SpringBoot 接入SSE实现消息实时推送的优点,原理以及实现
  • 【Linux系统】进程间通信:命名管道
  • 生成模型实战 | Transformer详解与实现
  • 分布式光伏气象站:安装与维护
  • 人大金仓数据库逻辑备份与恢复命令
  • 基于模式识别的订单簿大单自动化处理系统
  • Git 分支迁移完整指南(结合分支图分析)
  • JavaWeb(04)
  • 每日五个pyecharts可视化图表-bars(5)
  • SQL的条件查询
  • PDF注释的加载和保存的实现
  • jspdf或react-to-pdf等pdf报错解决办法
  • QT自定义控件
  • 学习日志29 python
  • 微信小程序多媒体功能实现
  • 大型音频语言模型论文总结
  • 使用Nginx部署前后端分离项目
  • 0806线程
  • MCU程序段的分类
  • http请求结构体解析
  • 【注意】HCIE-Datacom华为数通考试,第四季度将变题!
  • 时隔六年!OpenAI 首发 GPT-OSS 120B / 20B 开源模型:性能、安全与授权细节全解
  • Spring Boot部门管理系统:查询、删除、新增实战
  • 嵌入式处理器指令系统:精简指令集RISC与复杂指令集CISC的简介,及区别