2025/7/17 数据结构专题

2025/7/17 \(\mathbf{} \begin{Bmatrix} \frac{{\Large LEARN} }{{\color{Yellow}\Large Record} }\mathbf{} {No.9} \end{Bmatrix}\times{}\) NeeDna

题号 来源 知识点标签 难度(洛谷难度标记) 一句话题解(尽量) 备注(推荐理由,题目特点等等)
P7603 洛谷 省选/NOI− 减半警报器板子 见套路
P7560 洛谷 扫描线 省选/NOI− 消除离开不够,转化为扫描线板子 洛谷省选/NOI−题,扫描线应用,适合进阶训练
P9596 洛谷 线段树 省选/NOI− 转化,线段树维护 洛谷省选/NOI−题,经典转化思路,线段树练手好题,适合进阶训练
loj2461 LOJ 分块 经典分块问题 LOJ经典分块题,分块思想实践
P9968 洛谷 二进制 提高+/省选− 二进制分组,暴力 洛谷提高+/省选−题,适合提高训练
gym 102331F Codeforces 减半警报器板子 见套路
P4198 洛谷 线段树 省选/NOI− 斜率单调栈维护 洛谷省选/NOI−题,斜率优化经典题,线段树练手好题,适合进阶训练
CF765F Codeforces 线段树 NOI/NOI+/CTSC 线段树维护区间信息 Codeforces经典线段树题,线段树练手好题,适合进阶训练
P7561 洛谷 二分,扫描线 省选/NOI− 扫描线处理 洛谷省选/NOI−题,扫描线应用,适合进阶训练
CF803G Codeforces 线段树,st 表 省选/NOI− 线段树维护区间信息 Codeforces经典线段树,st 表题,线段树练手好题,适合进阶训练
CF193D Codeforces 线段树 省选/NOI− 线段树维护区间信息 Codeforces经典线段树题,线段树练手好题,适合进阶训练
CF377D Codeforces 扫描线,线段树 省选/NOI− 线段树维护区间信息 Codeforces经典扫描线,线段树题,线段树练手好题,适合进阶训练
CF1677E Codeforces 扫描线 省选/NOI− 扫描线处理 Codeforces经典扫描线题,扫描线应用,适合进阶训练
CF1446D2 Codeforces 根号分治 省选/NOI− 根号分治处理 Codeforces经典根号分治题,根号分治典型,适合进阶训练
CF436F Codeforces 分块,斜率优化 NOI/NOI+/CTSC 分块处理 Codeforces经典分块,斜率优化题,分块思想实践,适合进阶训练
UOJ812 UOJ 主席树 经典主席树问题 UOJ经典主席树题
UOJ515 UOJ Seg Beats 离线转化为 Seg Beats 板子 了解 Seg Beats
CF671E Codeforces 线段树 NOI/NOI+/CTSC 线段树维护区间信息 Codeforces经典线段树题,线段树练手好题,适合进阶训练
P4314 洛谷 历史最值 省选/NOI− 历史最值标记处理 洛谷省选/NOI−题,历史最值处理模板,适合进阶训练
P2048 洛谷 st 表 省选/NOI− ST表+堆维护前k大 洛谷省选/NOI−题,ST表应用经典,适合进阶训练
CF1491H Codeforces 树分块 NOI/NOI+/CTSC 分块处理 Codeforces经典树分块题,分块思想实践,适合进阶训练
P5355 洛谷 莫队,bitset 省选/NOI− 莫队+bitset维护 洛谷省选/NOI−题,bitset优化经典,莫队算法练习,适合进阶训练
UOJ671 UOJ 线段树 线段树维护区间信息 UOJ经典线段树题,线段树练手好题
QOJ6630 QOJ 线段树 经典线段树问题 QOJ经典线段树题,线段树练手好题
CF1270F Codeforces 根号分治 省选/NOI− 根号分治处理 Codeforces经典根号分治题,根号分治典型,适合进阶训练
UOJ169 UOJ 线段树 线段树维护区间信息 UOJ经典线段树题,线段树练手好题
CF1580C Codeforces 根号分治 省选/NOI− 根号分治处理 Codeforces经典根号分治题,根号分治典型,适合进阶训练
P7708 洛谷 回滚莫队 省选/NOI− 经典回滚莫队问题 洛谷省选/NOI−题,莫队算法练习,适合进阶训练
P4755 洛谷 CDQ 分治,树状数组 省选/NOI− 经典CDQ 分治,树状数组问题 洛谷省选/NOI−题,CDQ分治经典,适合进阶训练
P9062 洛谷 分块 NOI/NOI+/CTSC 分块处理 洛谷NOI/NOI+/CTSC题,分块思想实践,适合进阶训练
P3437 洛谷 树套树 提高+/省选− 经典树套树问题 洛谷提高+/省选−题,适合提高训练
P4098 洛谷 主席树 省选/NOI− 经典主席树问题 洛谷省选/NOI−题,适合进阶训练
P2839 洛谷 线段树 省选/NOI− 线段树维护区间信息 洛谷省选/NOI−题,线段树练手好题,适合进阶训练
CF1051G Codeforces 线段树合并,并查集 NOI/NOI+/CTSC 线段树维护区间信息 Codeforces经典线段树合并,并查集题,线段树练手好题,适合进阶训练
P3206 洛谷 CDQ 省选/NOI− 经典CDQ问题 洛谷省选/NOI−题,CDQ分治经典,适合进阶训练
P7602 洛谷 树状数组 提高+/省选− 经典树状数组问题 单 log 的套路可以积累
CF1172F Codeforces 线段树 NOI/NOI+/CTSC 线段树维护区间信息 经典线段树题,线段树练手好题,适合进阶训练
CF1340F Codeforces 线段树,分块 NOI/NOI+/CTSC 线段树维护区间信息 Codeforces经典线段树,分块题,线段树练手好题,适合进阶训练
CF1098D Codeforces set 省选/NOI− set维护有序信息 Codeforces经典set题,适合进阶训练
UOJ164 UOJ 线段树 线段树维护区间信息 UOJ经典线段树题,线段树练手好题
P3658 洛谷 CDQ,树状数组 省选/NOI− CDQ分治处理 洛谷省选/NOI−题,CDQ分治经典,适合进阶训练
loj3282 LOJ 线段树,最短路 线段树维护区间信息 LOJ经典线段树,最短路题,线段树练手好题
loj3038 LOJ 线段树 线段树维护区间信息 LOJ经典线段树题,线段树练手好题
P4602 洛谷 整体二分,树状数组 省选/NOI− 整体二分+树状数组 洛谷省选/NOI−题,整体二分应用,适合进阶训练
loj3030 LOJ 线段树,三位偏序 线段树维护区间信息 LOJ经典线段树,三位偏序题,线段树练手好题

P9968 [THUPC 2024 初赛] 二进制

题目描述

小 F 给出了一个这里有一个长为 \(n\) 的二进制串 \(s\),下标从 \(1\)\(n\),且 \(\forall i\in[1,n],s_i\in \{0,1\}\),他想要删除若干二进制子串。

具体的,小 F 做出了 \(n\) 次尝试。

在第 \(i\in[1,n]\) 次尝试中,他会先写出正整数 \(i\) 的二进制串表示 \(t\)(无前导零,左侧为高位,例如 \(10\) 可以写为 \(1010\))。

随后找到这个二进制表示 \(t\)\(s\) 中从左到右 第一次 出现的位置,并删除这个串。

注意,删除后左右部分的串会拼接在一起 形成一个新的串,请注意新串下标的改变。

若当前 \(t\) 不在 \(s\) 中存在,则小 F 对串 \(s\) 不作出改变。

你需要回答每一次尝试中,\(t\)\(s\) 中第一次出现的位置的左端点以及 \(t\)\(s\) 中出现了多少次。

定义两次出现不同当且仅当出现的位置的左端点不同。

做法

因为数字 \(n\) 最多有 \(\log n\) 位,所以我们把所有可能的答案都记下来,删除的时候标记偏移量,用桶存答案个数就可以了。\(O(n\log ^2 n)\)

CF803G Periodic RMQ Problem

题目描述

给你一个整数序列 \(a\),你要执行 \(q\) 次操作,分两种:

  • 1 l r x:将 \(a_l\sim a_r\) 赋值为 \(x\)
  • 2 l r:求 \(a_l\sim a_r\) 中的最小值。

我们认为这个问题太简单了,所以不直接给出 \(a\),而是给出长度为 \(n\) 的序列 \(b\),将 \(b\) 复制 \(k\) 份,拼在一起得到 \(a\)

做法

动态开点线段树解决修改,对于查询线段树上没有的节点直 接在\(b_n\) 上查就行。

细节:在我们上面保留的点的基础上,相邻两个已经保留的点之间的最小值也是需要的(但不需要整段的信息,因为不会有询问只询问这一段的一半,或者是修改一半,不然这一段就会被分成两段甚至更多),所以在上面的基础之上,我们把相邻两个点之间的最小值也插入进去做线段树就没问题了。

所以空间要开 4 倍。

P7560 [JOISC 2021] フードコート (Day1) 没懂

题意

维护 \(n\) 个序列,\(m\) 次操作。每次在 \([l,\,r]\) 的序列末尾加 \(k\) 个数字 \(c\),或者在开头删去 \(k\) 个数字(如果 \(k\) 大于等于序列长度则删完),或者查询序列 \(a\) 的第 \(b\) 个位置的数字。

做法

  • 发现离开人数不够很麻烦,考虑将不够的人数加在询问上就 可以不管了。

  • 现在问题变成区间加减,查寻第K 大,显然是扫描线板子。

P4198 楼房重建

题意

\(N\) 栋正在坐标轴上修建的楼房和 \(M\) 个时间节点,已知每个时间节点上会有一栋楼的高度发生变化。 问对于每个时间节点,小 A 在原点可以看到几栋楼房(基于日常生活理解)。

做法

• k递增才能看见考虑用线段树维护斜率最大值mx 和答案s。

• 如果改的是右儿子,就对左儿子没有影响。

• 如果改的是左儿子,就对右儿子的答案进行calc。如果 ki > mxlson,那对右儿子 calc,左儿子的 s 全赋成 0,反之 calc 左儿子。

P7603 [THUPC 2021] 鬼街 没听懂

P9596 [JOI Open 2018] 冒泡排序 2 没懂

题意

一个序列 \(A\) 的扫描次数为 \(\max_{i=1}^n \sum_{j=1}^i[a_j>a_i]\)

证明

发现一次操作必定将恰好一个 \(p\) 前面大于他的数换到他后面(排除没有的)。原式子相当于对于每个位置 \(p\) ,把其前面大于他的换到他后面需要的扫描次数取 \(\max\) ,即操作后对于每个位置其前面没有大于他的,序列 \(A\) 就是拍好序列。

发现同样的值只有最后一个位置 \(p\) 有用,一种值的答案为 \(\sum [A_i>v]-(n-p)\),其中可以把 \(n-p\) 看作后面比他大的值,因为如果后面有比他小的值 \(v2\) ,他的最后一个位置 \(p2>p\),一定有 \(\sum [A_i>v2]-(n-p2)>\sum [A_i>v]-(n-p)\) ,即值 \(v\) 一定不优。

做法

开棵权值线段树直接维护这个式子的最值,权值线段树支持区间加,维护最大值即可。

P9247 [集训队互测 2018] 完美的队列 没懂

题意

\(n\) 个队列,容量为 \(a_i\)\(m\) 次操作 \((l,r,x)\),向第 \([l,r]\) 个队列插入 \(x\),超出容量弹出队头。

求每次操作后全局颜色数量,\(n,m\le 10^5\)

P7561 [JOISC 2021] 道路の建設案

题意

求前 $k $ 大的曼哈顿距离,先考虑求第 \(k\) 大的距离。

做法

\(k\) 大的距离,比较套路的做法是二分答案,然后计算距离 \(\le dis\) 的点对数。

曼哈顿距离不好求,考虑转化为切比雪夫距离,原来的点 \((x,y)\to (x+y,x-y)\)

那么这就是一个经典的二维数点问题。

同时我们不需要真正数有多少点对,点对数 \(\ge k\) 时直接返回即可。

所以具体操作是对所有点按 \(x\) 坐标排序,用队列维护 \(x\) 坐标在 \(dis\) 范围内的点,同时用 set 维护队列中的点的 \(y\) 坐标。

值域为 \(S\) ,则时间复杂度为 \(\mathcal{O}((n+k)\log n\log S+k\log k)\)

#include<bits/stdc++.h>
#define int long long
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=2.5e5+10;
struct Node {int x,y;}t[MAXN];
int n,k,cnt;
vector<int> ans;
multiset<pair<int,int>> st;
int check(int len) {
	ans.clear(),st.clear();
	int pos=1; cnt=0;
	ffor(i,1,n) {
		if(i-1) st.insert({t[i-1].y,i-1});
		while(t[i].x-t[pos].x>len) st.erase({t[pos].y,pos}),pos++;
		auto it=st.lower_bound({t[i].y-len,0});
		while(it!=st.end()&&it->first<=t[i].y+len) {
			cnt++,ans.push_back(max(abs(t[i].y-it->first),abs(t[i].x-t[it->second].x))),it++;
			if(cnt>k) return 0;
		}
	}
	return 1;
}
void bfind(int l,int r) {
	int aans=0;
	while(l<=r) {
		int mid=l+r>>1;
		if(check(mid)) aans=mid,l=mid+1;
		else r=mid-1;
	}
	check(aans);
	ffor(i,1,k-cnt) ans.push_back(aans+1);
	return ;
}
signed main() {
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>k;
	ffor(i,1,n) {int x,y; cin>>x>>y,t[i]={x+y,x-y};}
	sort(t+1,t+n+1,[](Node A,Node B) {
		if(A.x!=B.x) return A.x<B.x;
		return A.y<B.y;	
	});
	bfind(1,4000000000);
	sort(ans.begin(),ans.end());
	for(auto v:ans) cout<<v<<'\n';
	return 0;
}

CF193D Two Segments 没懂

题意

给一个 \(1\sim n\) 的排列 \(a\),求有多少种选择两个不重叠的区间 \([l_1, r_1]\)\([l_2,r_2]\) 的方法让这些元素排序之后在值域里是连续的一段。\(1\le n\le 3\times 10^5\)

CF1677E Tokitsukaze and Beautiful Subsegments 没懂

题意

给定排列 \(\{p_n\}\),定义一个区间 \([l,r]\) 是好的,当且仅当存在 \(l \le i < j \le r\),满足 \(p_i\times p_j = \max\{p_l, p_{l + 1}, \dots, p_r\}\)\(q\) 次询问 \([l,r]\),求 \([l,r]\) 有多少个子区间是好的。\(n \le 2 \times 10^5, q \le 10^6\)

posted @ 2025-07-17 08:44  NeeDna  阅读(32)  评论(0)    收藏  举报