合集-数据结构
摘要:原题链接 题解 二分加动态维护区间最大值 注意设立变量的含义,改变变量值的规则 code #include<bits/stdc++.h> #define ll long long using namespace std; ll sum[500005]={0}; struct unit { ll x,
阅读全文
摘要:原题链接 题解 不能连续选k个元素 \(\to\) 任意每k个元素就有一个不选 \(\to\) 每k个点就有一个断点 \(\to\) 每个点都有可能是断点 \(\to\) dp求解 \(sol.1\) 令 \(f[i]\) 为第i个点为断点且为结尾的最大值 则 \(f[i]=max(f[j]+sum
阅读全文
摘要:原题链接 思路 求最大区间和 \(\to\) 设每个点为区间右端点时的最大区间和 \(f[i]\) ,则答案一定为 \(max(f[i])\) \(\to\) 求最大的 \(f[i]\) \(\to\) 每个 \(f[i]=max(sum[i]-sum[j-1]),j\in[i-k+1,i]\) \
阅读全文
摘要:原题链接 题解 直接插在它后面,这种数据结构是链表 赛时明明想到了链表,但是写的一团糟。。 对于链表,最简单的就是用map了 code #include<bits/stdc++.h> using namespace std; int a[200005]; map<int,int> head,to;
阅读全文
摘要:原题链接 题解 太巧妙了 把每个点上方的连续f长度记录下来,然后求每行的柱状图构成的矩形的最大面积 code #include<bits/stdc++.h> using namespace std; int f[1005][1005]={0}; int n,m; struct node { int
阅读全文
摘要:原题链接 题解 1.倒序求 2.求每个点前有多少高度比自己小的 3.高度函数图像是有升有降的,由于要求比自己小的,在求完之后,我们把所有点前比自己小的点缩起来放到自己身上,然后把那些点删掉,再插入自己 这样序列就变成了降序,遍历的时候也只需要遍历那些降序点 code #include<bits/st
阅读全文
摘要:原题链接 题解 原题等价于求以 \(i,(i>=k)\) 为右端点,长度为 \(k\) 的区间内的最大元素 \(\to\) 由于维护的区间是定值,所以我们可以用单调队列维护,单调队列中保证元素大小从头到尾降序,且下标升序 这样一来,我们便可以保证下标在指定范围内,然后取最大值也只需要 \(O(1)\
阅读全文
摘要:原题链接 题解 把覆盖的区域变成黑色,然后在区域内划几条竖线,一定能分成若干个矩形左右拼接而成的图形 想象一条竖着的线,它的运动轨迹是不连续的,即他会从一个矩形的竖边跳到另一个矩形的竖边,每跳一条竖边都会对借着竖边归属的矩形的信息对这条竖边的激活块进行修改 当竖线的绝对位置发生移动时,计算激活区间产
阅读全文
摘要:原题链接 题解 发誓以后除了stl内置,其他时候结构体绝对不内置比较函数 code #define ll long long #include<bits/stdc++.h> using namespace std; ll in_q[3005]={0}; ll h[3005]={0}; ll vis[
阅读全文
摘要:原题链接 题解 用由于本题具有线性特征(总是不减?)所以可以用两个堆来维护第i小的元素, code #include<bits/stdc++.h> using namespace std; int a[200005]; int main() { ios::sync_with_stdio(false)
阅读全文
摘要:原题链接 题解 1.该题等价于构建一颗k叉树,每个叶子节点都有一个权值 \(leaf_i\) ,树的权值为 \(\sum_{1}^{n}leaf_i\) ,在使树的权值尽可能小的情况下,使最深的叶子节点的深度也尽可能小,即使数的高度尽可能小 这个叫做哈夫曼树 2.构建过程如下:每次从队列中取出 \(
阅读全文
摘要:原题链接 题解 1.建议去B站上看看动画演示,你就明白怎么回事了 2.如何用代码实现呢?看完你就明白了 code #include<bits/stdc++.h> using namespace std; int num=0; int tree[3000006][75]={0}; int cnt[30
阅读全文
摘要:原题链接 题解 1.由于我刚刚才学字典树,所以我会告诉你这就类似字典树,对字符串终点节点加一,然后搜索统计最大前缀和 code #include<bits/stdc++.h> using namespace std; string s; int tree[2000005][65]={0}; int
阅读全文
摘要:原题链接 题解 1.字符串集合map?但是无法做到字典序排序,所以是字典树 2.n<=3000,所以 \(O(n^2)\) 而且本题的特殊性,即每个子串都要放进去,所以要在 \(n^2\) 一边遍历一边放 code #include<bits/stdc++.h> using namespace st
阅读全文
摘要:原题链接 题解 1.看到拼接,有种背包dp的感觉 所以方法1,暴力背包dp \(Code1\) #include<bits/stdc++.h> using namespace std; int vis[200005]={0}; vector<string> a; int main() { strin
阅读全文
摘要:原题链接 题解 dalao‘s blog 我自己的认识请看代码区 code #include<bits/stdc++.h> using namespace std; int n,Q,root,mod; int bigson[100005];//和自己在同一条链上的儿子节点 vector<int> G
阅读全文
摘要:原题链接 题解 本题的优化真的很重要!! 把所有元素出现的下标用map套vector存起来,然后二分查找 code #include<bits/stdc++.h> using namespace std; map<int,vector<int> > mp; int main() { ios::syn
阅读全文
摘要:原题链接 题解 找出右端点大于等于当前区间的左端点且左端点小于等于当前区间的右端点的所有区间,由于查询前这样的区间具有单调性,所以可以用二分,但是怎么快速删除呢? 欸stl大法来了,用set存储区间,查找和删除和添加都是 \(logn\) 级的 code #include<bits/stdc++.h
阅读全文
摘要:原题链接 题解 1.朴素想法:链表存储+每次遍历一遍找出最小对 缺点:时间复杂度过高 改进措施:每次遍历一遍,只会挑走一对,剩下的会重复遍历,所以我们把所有的对都找出来放进堆里,每次挑出第一个没有被用到过的对 注意审题 code #include<bits/stdc++.h> using names
阅读全文
摘要:原题链接 题解 注意数据范围 1.我们不知道要在哪些地方建站,所以考虑都遍历一遍 2.如果一个地方 \(i\) 要建站,那么在它前面且离它最近的一个站,一定建在所有右端点大于 \(i\) 的区间中,左端点最大区间里 所以我们令 \(dp[i]\) 表示为在 \(i\) 建立一个站,且和 \([1,i
阅读全文
摘要:原题链接 题解 一句话总结:第 \(i\) 头奶牛继承场上 \(k\) 头奶牛里结束时间最短的 code #include<bits/stdc++.h> using namespace std; int n,t; int d[100005]; int check(int k) { priority_
阅读全文
摘要:原题链接 题解 我一开始想着二位前缀和+模拟,但是看到ab发现空间不够 观察到nm的数据范围限制 也就是点和查询的数量限制,考虑用优先队列把各个方向的点存起来以表示各个点的使用顺序,再用map嵌套表示各个点的使用情况 空间复杂度 \(O(n)\) 时间复杂度 \(O(T(mlogn+nlogn))\
阅读全文
摘要:原题链接 题解 假如最后有 \(k\) 个月购买过幸福,那么这 \(k\) 个月的价格一定是前 \(k\) 小的 code #include<bits/stdc++.h> #define ll long long using namespace std; int main() { ios::sync
阅读全文
摘要:原题链接 题解 只要存在一对线段不相交就输出yes,显然空集合以及最小的r大于等于最大的l时一定不存在 code #include<bits/stdc++.h> using namespace std; int main() { int q; cin>>q; multiset<int> l,r; w
阅读全文
摘要:原题链接 题解 转换成有向无环图,可以发现,我们先将入度为0的节点输出总是不劣的 对于环,无论从哪里开始只会改变一个节点的双倍奖励,所以从奖励最小的点开始 由于存在多个环(见样例),所以我们可以用堆来维护所有点 code #include<bits/stdc++.h> using namespace
阅读全文
摘要:原题链接 题解 dp+多次优先队列 设 \(dp[i]\) 为 \([1,i]\) 区间内,前 \(k\) 个最大值(有可能不足k个)(注意 \(dp[i]\) 是一个序列) 则 \(dp[i]=\{dp[j][t]+a[j+2][i],j\in[0,i-2],t\in[0,top_j]\} ,\s
阅读全文
摘要:原题链接 题解 由于模拟会爆 longlong,所以用线段树维护每次操作的值,初始每次操作的值均为1 操作一令对应节点变为 m 操作二令对应节点变为 1 返回整棵树的值(相乘) code #include<bits/stdc++.h> #define ll long long using names
阅读全文
摘要:原题链接 题解 尽量直观地理解单调队列的作用 首先,对于合法的一段,有如下性质 A 满足: 当前的最高温度大于等于前面的最大的最低温度 该性质对于段内每一个数都满足,所以对于第 \(i\) 天,我们可以找其前面的第一天 \(j\) 的最低温度大于 \(i\) 的最高温度,同时还要满足 \((j,i]
阅读全文

浙公网安备 33010602011771号