一些数据结构杂题简要题解

[POI2015] Kinoman

二维数点问题,常用套路是,枚举其中一个端点,然后维护到每个端点的区间的值

设一部电影上一个播放日为 \(pre_i\),下一个播放日为 \(nxt_i\),发现每场电影 \(i\) 只有在 \(l > pre_i,r<nxt_i\) 的区间中对答案有贡献。

所以我们先将所有区间按照 \(pre_i\) 从小到大排序,从左到右枚举左端点,维护一棵以右端点为下标的线段树,每次将 \(pre_i<l\) 的点在区间 \([i,nxt_i)\) 加入贡献,并将 \(pre_i<l\) 的点的贡献删除,每次取全局最大值即可。

代码

ARC068E Snuke Line

对于每个 \(d\),如果一个商品的区间长度 \(\ge d\),那么这个商品一定会至少覆盖一个为 \(d\) 的倍数的点,所以直接计入贡献,而对于那些区间长度 \(<d\) 的商品,最多只会覆盖一个点,所以不会算重,直接树状数组进行区间修改、单点查询即可。

代码

CF749E Inversions After Shuffle

题意:给出一个 \(1 \sim n\) 的排列,从中等概率的选取一个连续段 \([l,r]\),设其长度为 \(l\)。对连续段重新进行等概率的全排列,求排列后整个原序列的逆序对的期望个数。

直接计算区间的期望不太好计算,由于期望的线性性,考虑计算每一组点对 \((i,j)\) 的贡献。

  1. \([l,r]\) 完全包含 \((i,j)\),逆序对的期望个数为 \(0.5\)。对答案的贡献为
    \[
    \frac{\sum \limits_{i=1}^{n} \sum \limits_{j=i+1}^{n} 0.5\times i (n-j+1)}{\frac{n(n+1)}{2}}
    = \frac{\sum \limits_{i=1}^{n} \frac{i(n-i+1)(n-i)}{2}}{n(n+1)}
    \]
    于是就可以 \(O(n)\) 地算出来了。
  2. \([l,r]\) 不完全包含 \((i,j)\)。若 \(w_i < w_j\) ,则对答案的贡献为 \(0\)。若 \(w_i > w_j\) ,逆序对的期望个数则为 \(1\),所以对答案的贡献为
    \[
    \frac{\sum \limits_{i=1}^{n} \sum \limits_{j=i+1}^{n} \frac{n(n+1)}{2} - i (n-j+1)}{\frac{n(n+1)}{2}} \= 1- \frac{\sum \limits_{i=1}^{n} \sum \limits_{j=i+1}^{n} i (n-j+1)}{\frac{n(n-1)}{2}} \= 1- \frac{\sum \limits_{i=1}^{n} i\sum \limits_{j=i+1}^{n}(n+1-j)}{\frac{n(n+1)}{2}},且w_i>w_j
    \]
    所以这部分只需要对每个位置用树状数组维护其后面比它小的数的数量以及位置的和即可。

    代码

CF901C Bipartite Segments

首先,“不含偶环的无向图”是仙人掌,而二分图的充要条件是不含奇环,所以诱导子图必须是不含环。

先用 \(\text{Tarjan}\) 缩点,求出每个环的编号范围 \([l,r]\),那么考虑对每个端点求出最大的合法的右端点 \(nxt_i\)。

对于每个询问,二分出使得 \(nxt_i\) 大于 \(y\) 的临界点。然后在临界点后的肯定无论如何都是合法的,直接计算即可。在临界点前的,利用 \(nxt_i\) 加个前缀和进行计算即可。

代码

CF903G Yet Another Maxflow Problem

首先将最大流转化为最小割。

显然 \(A_i\) 和 \(B_i\) 都最多只会割一条边,枚举割 \(A_i\),如果割 \(B_j\),那么对于所有的边 \((x,y),x\le i, y\ge j\) 都必须割掉。那么我们可以枚举 \(A_i\),然后维护一棵以 \(B_j\) 为下标的线段树,依次将与 \(A_i\)相连的边加入线段树中,查询每一个 \(A_i\) 的答案取 \(\min\) 即可。

然后对于修改操作,由于只修改 \(A_i\) 的边,所以每个 \(A_i\) 所对应的最优的 \(B_j\) 是不会变的,所以只需要将每个 \(A_i\) 的答案用线段树维护,单点修改,查询全局最小值即可。

代码

[HEOI2016/TJOI2016] 排序

考虑二分,每次二分出一个 \(mid\) 时,将大于等于 \(mid\) 的数记为 \(1\),小于 \(mid\) 的数记为 \(0\),这样对于 \(01\) 串每次排序就只是 \(\log n\) 的了。最后再看一下第 \(q\) 位是否为 \(1\),如果为 \(1\) 说明答案可以更大。

代码

[SCOI2016] 萌萌哒

第一想法是线段树优化连边,但是由于线段树的可能会让两个对应区间的切割方式不一样,所以还是 \(O(N^2)\) 的。

考虑用 \(ST\) 表优化连边,令 \(fa[i][j]\) 表示 \(i\) 往后长度为 \(j\) 的区间在并查集上的父亲。然后标记下放即可。

代码

[2017 山东二轮集训 Day7] 国王

设 \(A\) 为两个端点都在 \([l,r]\) 中的合法路径条数,\(B\) 为两个端点都不在 \([l,r]\) 中的合法路径的条数,\(C\) 为两个端点不在同一个区间内的合法条数。

我们这里要求的是 \(A-B\),显然直接求不太好求,考虑我们求出 \(f_i\) 表示以 \(i\) 为其中一个端点的路径数,\(sum\) 表示总路径数,那么
\[
2A + C = \sum\limits_{i=l}^{r} f_i \2B + C = 2 \times sum - \sum\limits_{i=l}^{r} f_i
\]
所以
\[
A - B = \sum \limits_{i=l}^{r} f_i - sum
\]
还是枚举左端点,显然合法的右端点是单调递增的。然后 \(f_i\) 可以利用点分治求。

原文地址:https://www.cnblogs.com/newbielyx/p/12210058.html

时间: 2024-11-08 00:06:27

一些数据结构杂题简要题解的相关文章

51nod 最近刷题 简要题解

51nod 1564 由于数据是随机的,可以证明,对于每一个数,向左或右找比它小的数,长度是logn级别的 考虑枚举最大值 注意,对于每一个最大值,如果直接用2个循环枚举左右端点的话,理论是lognlogn级别的,但是还是很容易被卡的,换成贪心,用2个指针指着左右端点,每一次移动我们往数大的那个方向移动 代码: //File Name: nod1564.cpp //Author: long //Mail: [email protected] //Created Time: 2016年10月10日

杂题记录及简要题解(三)

以下是大概 5 月初开始做的一些题.以前的简要题解都是骗人的.这次真的是简要题解了(大雾 相对之前改良了一下题目名称的格式. 2017 计蒜之道 初赛 - 腾讯狼人杀 二分答案 \(x\) 后原问题变为检验是否存在选取方案 \((V, E)(|V| = k)\) 使得 \(\sum_\limits{e \in E} w_e - xk \cdot (2n- k)\).式子可以写成 \(\sum_\limits{e \in E} w_e + \frac{k(k - 1)}{2} \cdot 2x -

AGC025简要题解

AGC025简要题解 B RGB Coloring 一道简单题,枚举即可. C Interval Game 考虑可以进行的操作只有两种,即左拉和右拉,连续进行两次相同的操作是没有用的. 左拉时肯定会选择右端点尽量小的,右拉选择左端点尽量大的,所以排序之后贪心即可. D Choosing Points 首先证明对于所有\(d\),假设让两个不能同时选的点之间连一条边,那么结果是一张二分图. \(d\)是奇数可以黑白染色,\(d\)是偶数的时候,显然连边的两点在同一个颜色内.那么我们可以只考虑这个颜

月考简要题解

模拟赛简要题解 一下题目均可在loj上找到 10178. 「一本通 5.5 例 4」旅行问题 简单题,将n扩大到2 * n,单调队列即可,注意正反向. #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int N=2000

杂题选录

LuoguP3948数据结构 10-20 是比较裸的差分题目,但是要注意在线查询的时候开始傻了,每次都暴力地从1到n搞一遍,还存在数组中每次都要清空...结果T了很多点. 其实在线查询的时候直接用变量+扫到r就行了. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 5 using namespace std; 6 typedef long long ll; 7 8 int n,opt,tot,

JXOI2018简要题解

JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法描述大致如下: 假设我们要对一个大小为 \(n\) 的数列 \(a\) 排序. 等概率随机生成一个大小为 \(n\) 的排列 \(p\) . 构造一个大小为 \(n\) 的数列 \(b\) 满足 \(b_i=a_{p_i}\) ,检查 \(b\) 是否有序,如果 \(b\) 已经有序了就结束算法,并

BJOI2018简要题解

BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生成了一个长为 \(n\) 的二进制串,希望你对于这个二进制串的一个子区间,能求出其有多少位置不同的连续子串,满足在重新排列后(可包含前导 \(0\))是一个 \(3\) 的倍数.两个位置不同的子区间指开始位置不同或结束位置不同. 由于他想尝试尽量多的情况,他有时会修改串中的一个位置,并且会进行多次询

《信奥一本通》提高版—简要题解

<信奥一本通>提高版-简要题解 贪心 活动安排: 按右端点排序,因为越早结束越好. 然后从1扫到n,每次比较当前位置线段的左端点是否大于上一个选的线段的右端点.如果大于,那么ans++,将上一个选的线段的右端点更新为当前线段的右端点:如果小于,那什么都不用做.因为选上一条一定比选当前这一条更优(结束时间更早). 种树 按右端点排序,对于每个区间的需求,从右端往左端扫,只要没种到树的就种,ans++. 因为要使前面的需求尽量与后面的需求重叠,从而使树的数量最少 喷水装置 观察+画图发现对于一个圆

【最小生成树杂题】

这里谈一下最小生成树 生成树的概念:连通图G的一个子图如果是一棵包含G的所有顶点的树,则该子图称为G的生成树.生成树是连通图的极小连通子图.所谓极小是指:若在树中任意增加一条边,则将出现一个回路:若去掉一条边,将会使之变成非连通图. 生成树各边的权值总和称为生成树的权.权最小的生成树称为最小生成树. 最小生成树一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边.常用于求最小生成树得算法包括kruskal(克鲁斯卡尔)算法或Prim(