07 2020 档案
摘要:这次集训,我的收获如下。 自己想出了动态开点线段树、 口胡出了空间复杂度的动态开点权值线段树代替主席树。 学习了后缀数组,字典树。 学习了插头dp与数位dp 学习了A* 学习了基环树dp与仙人掌 学习了决策单调性优化dp 学会了打表当然是法老教的 看到了我和人家的差距(人家三场阿克,我加
阅读全文
摘要:题面传送门 间隔染色然后跑二分图即可。 不得不说的数据一点没改可还行 复杂度 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b))
阅读全文
摘要:题面传送门 这个对于每个边跑拓扑序即可,如果有环那么不可行,如果两个字母拓扑序相同也不可行。 代码实现: #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; int n
阅读全文
摘要:题面传送门 直接建分层图跑即可。 注意一些细节即可。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define abs(x) ((x)>(0)?(x):-(x)) #define max(a,b) ((a)>(b)?
阅读全文
摘要:题面传送门 直接跑二分图最大匹配即可。 关于输出方案看哪条边没有权值就输出两个端点即可。 代码实现: #include<cstring> #include<cstdio> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)) using namespa
阅读全文
摘要:题面传送门 显然对列数奇偶性染色然后建边跑二分图即可。 注意无法放置点可能重复。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)) using namespace s
阅读全文
摘要:题面传送门 显然是二分图建模板子题。 观察可得,可以黑白染色建图。 那么从黑格向白格建边跑二分图最小点覆盖即可,注意要用全部点减去最小点覆盖。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)
阅读全文
摘要:题面传送门 数据这么小,一看就可以 外层循环就是允许点转移,那么题目中依次给出允许点转移顺序,那么直接可以做了。 代码实现: #include<cstdio> #include<cstring> #include<algorithm> #define max(a,b) (
阅读全文
摘要:题面传送门 一道二分图建模的好题。 题目中要求最少覆盖,很容易想到最小点覆盖,也想到了二分图。 把横竖模板铺出来,可以贪心,一定是延展到最长最优。 那么把图建出来后跑最小点覆盖即可,可以得出最小点覆盖等于最大匹配数。 代码实现: #include<cstdio> #include<cstring>
阅读全文
摘要:题面传送门 对于左部点建超级原,右部点建超级汇,边权为跑即可,这样超级原控制了每个点只能走一次。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)
阅读全文
摘要:题面传送门 直接上板子即可,注意加几个剪枝,跑得飞快。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define min(a,b) ((a)<(b)?(a):(b)) using namespace std; i
阅读全文
摘要:题面传送门 先两遍跑出树的直径。 因为所有树的直径都是相类似的,所以只要跑一条直径就好了。 然后在这条直径上尺取。 最后对于直径上每个点的子树不经过直径上的边求距离取最大值即可,这一步很难想,因为如果不取最大值那么就会漏掉答案因为无论如何都是要有这条边的权值的。 完美 代码实现
阅读全文
摘要:题面传送门 对于一个点,考虑如果把它和它的子树断开来。 断主要边肯定是断和父节点连着的边。 断次要边统计子树内有几条次要边连向外面。 如果只有一条,那么就断这一天, 如果没有,那么随便断,加上次要边边数即可。 统计子树内边数可以用树上差分 时间复杂度 代码实现:
阅读全文
摘要:题面传送门 题目要求个连接关键点的边权之和的二倍。 那么 那么加入或删除一个点时对左右两边拆边建边即可。 维护左右两边可以用平衡树维护,这里写了一个非递归式权值线段树维护。 时间复杂度$O(nl
阅读全文
摘要:题面传送门 感觉就像一道裸题。 转化成前缀和然后建边即可。 注意前缀和特性: 所以按照这个建边就好了。 代码实现: #include<cstdio> #include<cstring> #include<queue> #define
阅读全文
摘要:题面传送门 空间这么小,只能莫队。在移动时用域值分块修改即可。 代码实现: #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int n,m,k,x,y,z,ans[1000039],a[1
阅读全文
摘要:题面传送门 如果显然非常简单,取树的直径即可。 考虑怎么做。 第一条显然要取树的直径。 而第二条如果围成的环和第一条围成的环有重叠,那么重叠的边要走两次。所以我们可以把这几条重叠的边权值设为,然后再跑一遍树的直径。 代码实现: #include<cstdio> #incl
阅读全文
摘要:题面传送门 显然是个结论题。 可以发现,对于每个点,两棵子树肯定差值不大于,而且如果差值为一,那么最晚更新点在左子树,反之在右子树。 然后预处理幂递归即可。 代码实现: #include<cstdio> #define mod 1000000007 using namespace std; i
阅读全文
摘要:题面传送门 首先把最小生成树跑出来。 然后因为要次小,那么枚举未被选的每一条边。加入树中,构成了一个环,然后在这个环上找严格次小值即可。 关于严格次小值可以用树上倍增求出。 时间复杂度,其中在这道题中约取 还有一个小
阅读全文
摘要:题面传送门 可以发现大小具有单调性,所以可以二分。 二分后用背包验证可行性即可。 代码实现: #include<cstdio> #include<cstring> #include<algorithm> #define max(a,b) ((a)>(b)?(a):(b)) using nam
阅读全文
摘要:题面传送门 显然最长的一条是树的直径。 那么找到树的直径后另一条枚举点然后跑即可。 代码实现: #include<cstdio> #include<queue> #include<cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define ma
阅读全文
摘要:题面传送门 显然可以莫队,而且是板子题。 但是考虑怎么在过程中增加和修改,无论怎样写树形结构都会使复杂度飙升到 这时可以暴力数据结构:分块,单点修改,查询 这样复杂度就是妥妥的 代码实现: #include<c
阅读全文
摘要:题面传送门 这道题是树的直径裸题。 显然跑两遍找树的直径即可。 但是输入很毒瘤。 所以要信仰啊 代码实现: #include<bits/stdc++.h> using namespace std; int n,m,k,x,y,z,ans,tot,pus,flag
阅读全文
摘要:题面传送门 题目中要求最小路径生成树的方案数。 先跑一遍把最小路径跑出来,然后对于每个点枚举边,看看有几个点是可以转移,然后乘法原理计数即可。 代码实现: #include<cstdio> #include<cstring> #include<queue> #include<algori
阅读全文
摘要:题面传送门 题目大意:构造一个完全图,使得在最小生成树唯一(题目中给出)的情况下权值总和最小。 直接克鲁斯卡尔模拟,在合并两棵树时进行操作。 合并两棵树时要连的边的条数是,即将合并的这条边一定是两棵树中最大的边,而所有不在最小生成树内的边一定大于这条边,所以
阅读全文
摘要:题面传送门 按照题意模拟即可,把每个点的子树节点数遍历出来,然后与取绝对值即可。 代码实现: #include<cstdio> #include<cstring> #define abs(x)((x)>0?(x):-(x)) using namespace std; int n,m,k
阅读全文
摘要:题面传送门 这道题看上去是裸的最短路。 但是众所周知,经常卡。 所以不能用 又因为堆优化只能跑正权边。 所以发现一下题目的特殊性质: 事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台 了一些政策保证:如果有一条航线可以从 到
阅读全文
摘要:题面传送门 这道题两种解法。 第一种直接跑分层图最短路(或者叫二维)即可,时间复杂度。不过如果特殊数据会被卡到(好像还没有直接跑快) 第二种二分+最短路 我们肯定把一条路径中前大的点拿来免费,把第的点拿来支付。易得这种贪心是正确
阅读全文
摘要:题面传送门 直接树剖即可。用线段树维护两端点。合并时分类讨论一下要不要减即可。 注意,最后要把左边的左右端点翻转,可以画个图理解一下。 最后两个点在一条重链上时放在哪一边要反过来。 代码实现: #include<cstdio> #include<cstring> using namespace st
阅读全文
摘要:题面传送门 稍微看一下就可以得出结论:一个人获得的硬币数就是以这个点为根子树内所有节点的深度和。 那么树形就可以直接处理。 代码实现: #include<cstdio> #include<cstring
阅读全文
摘要:题面传送门 一眼 但是题目中说价格没有单调性,所以要先预处理出后缀 然后枚举断点即可。 代码实现: #include<cstdio> #include<algorithm> #include<cstring> #define min(a,b) ((a)<(b)?(a):(b)) u
阅读全文
摘要:题面传送门 显然,前面查询很少,可以直接差分。 后面前缀和即可。 代码实现: #include<cstdio> using namespace std; int n,m,k,x,y,z,maxn,minn,mod,fin,ans,tot; char _s; long long a[80039],q[
阅读全文
摘要:题面传送门 感觉这道题比还卡常。 显然可以直接开个线段树暴力做,复杂度 但是这样拿不了几分。 但我们注意到这是权值树。而且所有的权值树的权值之和等于,而我们开了的空间。所以势必有很大的空间与时间浪费。所以在当前点没有权值时就不必查找,当前点
阅读全文
摘要:题面传送门 很好的一道构造题。 显然答案就是或者 因为不存在两行或两列差值大于的。 那么沿着对角线依次左移即可,用一个循环队列实现。 代码实现: #include<cstdio> #include<cstring> using namespace std; int n,m,k,x,
阅读全文
摘要:题面传送门 把第一类客人转换一下,就是哪个多吃哪个。 第二类客人就是哪个少吃哪个。 很容易发现第二类客人最多能满足个,那么剩下的看第一类客人能否满足即可。 代码实现: #include<cstdio> #define max(a,b) ((a)>(b)?(a):(b)) #def
阅读全文
摘要:题面传送门 又是一道分类讨论的题目。 如果,那么其实与的任何值是一样的,所以可以忽略。而又只有一个答案,那么答案就是 反之,答案就是一个普通等差数列 代码实现: #include<cs
阅读全文
摘要:题面传送门 显然不可以最长路。 司机肯定喜欢走长的路径,所以先把最大生成树跑出来。 然后再最大生成树上跑倍增不就好了? 代码实现: #include<cstdio> #include<cstring> #include<algorithm> #define min(a,b) ((a)<(b)?(a)
阅读全文
摘要:题面传送门 显然可以四分树。 就是在线段树上加两个维度即可。 注意边界值。 代码实现: #include<cstdio> #define max(a,b) ((a)>(b)?(a):(b)) using namespace std; int n,m,k,x,y,z,sx,sy,sz,f[160000
阅读全文