摘要: P1257 平面上的最接近点对 这是最基础的问题哦。 两种思路。 一:暴力 我们可以直观地发现两个最近的点x坐标距离应该也比较近。所以我们可以考虑对于每一个点扫描离其最近的10个左右的点。 但是出题人可能会专门卡。所以我们把坐标轴旋转一个角度(旋转所有的点就可以),最短距离不变。 旋转方法即使用复数 阅读全文
posted @ 2021-09-03 21:44 lei_yu 阅读(23) 评论(0) 推荐(0) 编辑
摘要: 神奇分治,没想到吧 按照x坐标排序。把点分成两部分。 递归统计内部答案 分治主要考虑怎么合并两部分的答案: 首先要距离中间点小于当前ans的点。 然后把这些数按照y排序。 枚举即可。但是我们要记得及时退出。 可以证明对于一个左边的点,右边需要判定的点在三个以内。因为需要保证同侧不会出现更优答案。 # 阅读全文
posted @ 2021-09-03 19:03 lei_yu 阅读(49) 评论(0) 推荐(0) 编辑
摘要: 换根操作不用真的换根 发现只有子树操作有影响。 而且是修改的点是新根的祖先的时候有影响。 当前点往新根那个方向的子树都不能计算进去,其他全部计算即可。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> 阅读全文
posted @ 2021-09-03 18:57 lei_yu 阅读(18) 评论(0) 推荐(0) 编辑
摘要: 如果出现某些询问一堆东西的和的时候(如LCA的深度和),我们可以考虑不要把这些东西每一个都全部求出来,而应该考虑合并这些询问然后一次性询问他们的和。(例如用树剖转化为区间加和和区间询问) 具体思路见hzw博客 #include<iostream> #include<cstdio> #include< 阅读全文
posted @ 2021-09-03 18:54 lei_yu 阅读(25) 评论(0) 推荐(0) 编辑
摘要: #询问一个区间是否为一个排列,通常记录左右第一个在哪里出现。 从两遍往中间扫,发现某一个点满足第一个左右两边的数都不在当前区间范围内,那么他可以把区间分为两个部分且他自己满足条件,(因为要连续)继续递归求解即可。 由于两边同时计算,复杂度为$O(nlogn)$ #include<iostream> 阅读全文
posted @ 2021-09-03 18:44 lei_yu 阅读(25) 评论(0) 推荐(0) 编辑
摘要: 动态树形dp模板题 首先有sigma肯定不能矩阵优化了。 于是我们定义g(x)表示轻儿子的全部贡献,这样每一次修改只会修改logn次g(重链剖分的性质) 由于dp边界在叶子结点,我们需要记录每一条重链的结束位置。 用线段树统计一路上来矩阵乘法的值,该修改的修改最后询问根就是答案了。 (还是序列上的简 阅读全文
posted @ 2021-09-03 18:41 lei_yu 阅读(32) 评论(0) 推荐(0) 编辑
摘要: 每道题对期望贡献可以单独计算。 因为它们不会互相影响。 显然一道题做对的概率=期望=\(\frac{min(n,m)}{nm}\) #include<bits/stdc++.h> using namespace std; #define orz cout<<"lyakioi!!!!!!!!!!!!! 阅读全文
posted @ 2021-09-03 18:37 lei_yu 阅读(25) 评论(0) 推荐(0) 编辑
摘要: 其中一条道路的期望贡献为 \(\huge{\frac{dis}{s}}\) 全部的期望为 \(\huge{\frac{\sum dis}{s}}\) 其中s为路径条数 建反图拓扑排序就能求出。 #include<bits/stdc++.h> #include<queue> #define int l 阅读全文
posted @ 2021-09-03 18:35 lei_yu 阅读(18) 评论(0) 推荐(0) 编辑
摘要: 贪心,能倒就倒,能往左就往左实在不行往右 因为倒不倒都只影响下一棵树 大不了下一个不倒还对后面更优。 #include<bits/stdc++.h> using namespace std; #define orz cout<<"lyakioi!!!!!!!!!!!!!!!!!"<<endl inl 阅读全文
posted @ 2021-09-03 18:28 lei_yu 阅读(34) 评论(0) 推荐(0) 编辑
摘要: A从来不会难,就是一个简单的构造。 从样例就可获得启发 利用 \(1\) \(1+k\) \(1+k-(k-1)\) \(1+k-(k-1)+(k+2)\) 这样的方式,正好$k$个数便可以满足有k种不同差值的数。 因为$n>k$,所以必然正确。 后面就k+1,k+2,...,n即可 #includ 阅读全文
posted @ 2021-09-03 18:27 lei_yu 阅读(28) 评论(0) 推荐(0) 编辑
摘要: 贪心。 从最小的马开始考虑。我们肯定优先让这匹最小的马赢。 实在赢不了了就去自杀。这样可以保证最优,因为不管哪匹马都是一样的代价,虽然小的把可以赢的位置占了,但是大的可以有更多机会赢其他马,所以这样是对的。 但是还要考虑平局。 平局到底打不打? 要分情况讨论。 1、如果有一个更大的马只能自杀,那我们 阅读全文
posted @ 2021-09-03 18:24 lei_yu 阅读(27) 评论(0) 推荐(0) 编辑
摘要: 一般的树上贪心都是从叶子贪到根,这样才能保证最优。 所以这个题就是从叶子开始贪心就可以,正确性显然。 #include<bits/stdc++.h> #define int long long using namespace std; #define orz cout<<"lyakioi!!!!!! 阅读全文
posted @ 2021-09-03 18:19 lei_yu 阅读(71) 评论(0) 推荐(0) 编辑
摘要: 比较神奇的一道贪心/思维题 令i指向a[i]离散化后的值,显然会出现一些环的图。 一定是在环内交换,否则不可能更优。 如何交换? \(1>2>3>4>1\) 通过模拟,我们可以发现两种交换方式: 1 2 2 3 3 4 4 1 3 1 2 1 明显第二种更优 然后就WA了。 可以发现如果环外如果有一 阅读全文
posted @ 2021-09-03 18:18 lei_yu 阅读(48) 评论(0) 推荐(0) 编辑
摘要: 第一眼以为能用最大子段和 然后发现n很小,直接暴力 贪心取出最小加入最大即可。 #include<bits/stdc++.h> using namespace std; #define orz cout<<"lyakioi!!!!!!!!!!!!!!!!!"<<endl inline int r() 阅读全文
posted @ 2021-09-03 18:11 lei_yu 阅读(20) 评论(0) 推荐(0) 编辑
摘要: 神仙题,让我学会了NEW东西。 考虑到人实在太多了,不能直接把编号记录下来。我们可以使用 动 态 开 点 \(s\ p\ l\ a\ y\) 具体地,splay的每一个结点存储一段编号连续的区间,splay的内部根据排名排序。 每一次询问拆点即可。 实现稍(fei)微(chang)麻烦一些。 #in 阅读全文
posted @ 2021-09-03 18:09 lei_yu 阅读(32) 评论(0) 推荐(0) 编辑
摘要: 思考的突破口是最大的那个人连着的所有人都会死 进而我们可以想到一个人如果连着比他大的人那他就biss,因为比他大的人一定在他之后死,这条边就一直存在。 需要统计连着的比他大的人的数量,否则复杂度爆炸 #include<bits/stdc++.h> using namespace std; #defi 阅读全文
posted @ 2021-09-03 17:39 lei_yu 阅读(47) 评论(0) 推荐(0) 编辑
摘要: 二分答案。 考虑边肯定还是根据边权从小到大加入。 显然我们不能先加一堆白边。 但是我们可以通过白边的边权控制加入最小生成树的白边数量。 那么数量满足单调性可以二分。 #include<bits/stdc++.h> using namespace std; #define orz cout<<"lyt 阅读全文
posted @ 2021-09-03 17:33 lei_yu 阅读(36) 评论(0) 推荐(0) 编辑
摘要: 度限制最小生成树 就是01分数规划,裸的。 #include<bits/stdc++.h> using namespace std; #define orz cout<<"lytcltcltcltcltcltcl"<<endl inline int r(){int s=0,k=1;char c=ge 阅读全文
posted @ 2021-09-03 17:30 lei_yu 阅读(22) 评论(0) 推荐(0) 编辑
摘要: 度限制最小生成树。 先不加连跟的边,跑出其他的x个最小生成森林。 用最小代价的边链接根和森林,得到x度时的最小生成树。 如果度限制小于x,无解 如果度大于x,我们需要继续加链接根的边。 每一次枚举所有可能可以加入的边,找到加入后形成的环上不与根链接的边中最长的那一条删掉。在所有能加入的边中取最优的。 阅读全文
posted @ 2021-09-03 17:26 lei_yu 阅读(31) 评论(0) 推荐(0) 编辑