ABC372 (D,E)
ABC372 (D,E)
D
一道比较简单的二分查找题目。
观察到每个数能成为 \(j\) 的条件是独立的,因此想到统计每个数能成为它前面哪些数的 \(j\)。
对于每个\(ed\), 二分 \(1 \sim ed-1\) 中最后一个大于 \(h[ed]\) 的数的位置 \(st\), 那么 \(h[ed]\) 可作为 \(st \sim ed-1\) 的 \(j\).
二分的检查方法中需要求区间max, 写个st表或者线段树就做完了(参考代码用的线段树)
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long;
const int N = 3e5 + 5;
int h[N], ans[N], mx[N << 2];
int n;
void pushup(int u){
mx[u] = max(mx[u * 2], mx[u * 2 + 1]);
}
void update(int u, int l, int r, int x, int y){
if(l == r) {
mx[u] += y;
return ;
}
int mid = (l + r) >> 1;
if(x<=mid) update(u * 2, l, mid, x, y);
else update(u * 2 + 1, mid + 1, r, x, y);
pushup(u);
}
int query(int u, int l, int r, int x, int y){
if(x <= l && r <= y){
return mx[u];
}
int mid = (l + r) >> 1, ret = 0;
if(x <= mid) ret = query(u * 2, l, mid, x, y);
if(y > mid) ret = max(ret, query(u * 2 + 1, mid + 1, r, x, y));
pushup(u);
return ret;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n;
F(i, 1, n) cin >> h[i], update(1, 1, n, i, h[i]);
F(i, 1, n){
int l = 0, r = i, mid;
while(l + 1 < r){
mid = (l + r) >> 1;
if(query(1, 1, n, mid,i-1) > h[i]) l = mid;
else r = mid;
}
ans[l] ++, ans[i]--;
}
F(i, 1, n) ans[i] += ans[i - 1], cout << ans[i] << ' ';
return 0;
}
E
关键在于要读懂 type2 考察的对象是 \(u\) 所在连通块,想到这个,并查集就呼之欲出了。
而查询第 \(k\) 大的话,由于 \(k\) 不超过10, 所以暴力查是可以接受的。
合并用启发式合并保证复杂度控制在 \(O(n logn)\).
#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long;
const int N = 3e5 + 5;
int n, q;
int fa[N];
set<int,greater<int>> s[N];
inline int get(int x){
return (fa[x] != x) ? fa[x] = get(fa[x]) : x;
}
void merge(int u, int v){
int fu = get(u), fv = get(v);
if(fu == fv) return ;
if((int)s[fu].size() > (int)s[fv].size()){
fa[fv] = fu;
for(auto x : s[fv]){
s[fu].emplace(x);
}
s[fv].clear();
}
else{
swap(fu, fv);// fu:bigger
fa[fv] = fu;
for(auto x : s[fv]){
s[fu].emplace(x);
}
s[fv].clear();
}
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> q;
F(i, 1, n) fa[i] = i, s[i].emplace(i);
F(i, 1, q){
int op, u, v;
cin >> op >> u >> v;
if(op == 1){
merge(u, v);
}
else{
u = get(u);
if((int)s[u].size() < v){
cout << "-1\n";
continue;
}
for(auto x : s[u]){
if(--v==0){
cout << x << '\n';
break;
}
}
}
}
return 0;
}
随机推荐
- MySQL手动执行rollback,内部实现分析
-- 测试手动回滚操作 -- 1手动开启事务 START TRANSACTION -- 2执行更新操作语句 UPDATE FraBakNtuAnalysize SET IsDeleted = 0 WH ...
- 9. 从0学ARM Cortex-A9 LED汇编、C语言驱动编写
0. 前言 一般我们购买一个开发板,厂家都会给出对应的电路图文件,我们可以通过搜索对应名称来查找到对应的外设.对于驱动工程师来说,我们只需要知道外设与SOC交互的一些数据线和信号线即可. 用主控芯片控 ...
- Superset导航栏高亮问题处理
在superset => templates => appbuilder 文件夹下找到 navbar.html 如果没有可对应新建,navbar.html内容如下 {% set menu ...
- macOS 扫描局域网设备
arp-scan: arp-scan 是一个直接用于扫描本地网络中的设备的 UNIX 工具.这不是 macOS 自带的,但可以使用 Homebrew 安装.首先安装 Homebrew(如果尚未安装), ...
- ArgoWorkflow教程(三)---使用 Artifacts 实现步骤间文件共享
上一篇我们分析了 Workflow.WorkflowTemplate.template 之间的关系.本篇主要分析如何在 argo-workflow 中使用 S3 存储 artifact 实现步骤之间的 ...
- Pandas从入门到放弃
公众号本文地址:https://mp.weixin.qq.com/s/mSkA5KvL1390Js8_1ZBiyw Pandas简介 Pandas是Panel data(面板数据)和Data anal ...
- SpringMVC初体验
目录 SpringMVC简介 MVC介绍 什么是SpringMVC SpringMVC的特点 入门案例 创建maven工程 配置web.xml 默认配置方式 扩展配置方式 url-pattern标签中 ...
- redis zset 使用场景
前文,我们讨论过redis 的数据结构及使用场景.可参考: 参考: 总结篇4:redis 核心数据存储结构及核心业务模型实现应用场景 https://www.cnblogs.com/yizhiamum ...
- Unity 刚体 AddForce 的几种力类型
今天在实现 2D 横版跳跃的时候,发现使用AddForce添加的力太突兀了,没有逐渐向上的过程,发现AddForce还有ForceMode mode参数 以下部分内容摘自Bing Copilot总结 ...
- CSS 实现滑动整个元素
其实没什么难点,主要就是两个CSS属性 scroll-snap-type 这个是作用在包裹容器身上的. scroll-snap-align 这个是作用在被包裹容器身上的. 效果如下图所示: 代码如下: ...