03 2021 档案
摘要:分层图+最短路算法 对于题目当中的条件进行转化,相当于允许一条边代价为0,一条边代价为两倍,且必须要两种情况都使用。 因此考虑建立分层图,这样的话,分成四层,就能够先0后2倍,先两倍后0,两种情况都能表达了 此外,由于由于存在一条边即作为最小值也作为最大值,我们要连一条直接从1到第四层的边 #inc
阅读全文
摘要:#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; const int mod=1e9+7; int cnt; int id1[18*N],id2[18*N]; struct n
阅读全文
摘要:这道题强制在线,那么考虑在线算法 好像复杂度低的可以使用平衡树,但是我们这里使用分块算法 因为数据量不是特别大 因为是在前面加一个后面删一个,所以我们考虑使用双端队列来维护这个信息 这样修改的时候,可以把前面的块的末尾加到后面的块,这样每块的大小都不会发生改变 #include<bits/stdc+
阅读全文
摘要:显然不能暴力求解,进一步发现性质,我们要求的是每一个都满足限制。 正难则反,用总方案数-至少一种不满足的方案数 后面那个可以看得出来和容斥定理有关,因此考虑容斥,某个物品不满足,说明他至少取了d[i]+1个,其他随意,因此我们就求出了解答 #include<bits/stdc++.h> using
阅读全文
摘要:因为要求所有的状态,所以暴力超时 那么想想能否计算贡献。 我们对于每一个xi,xi+1,他们对于每一个fi的状态都有不同的贡献,因此我们枚举情况后用差分数组维护贡献 #include<bits/stdc++.h> typedef long long ll; using namespace std;
阅读全文
摘要:这种置换题一般都与图论结合 这题也不例外,显然绕一圈就是一个环 而使得全部回到原位就是每个环的lcm 在不考虑自环的情况下,我们求的就是大小为n,进行集合划分,求每个集合得lcm 这里又要进行一步转化,由于当每个集合互质的时候,lcm每次都不相同,我们只要枚举质数做完全背包就能求出方案数 假设一个集
阅读全文
摘要:A题 对于两个分别求解到每一位的时间,看看是否有相等的 #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; const in
阅读全文
摘要:A题 分奇偶讨论 B题 猜结论找规律题 C题 首先可以发现一个性质,这也是绝对值的性质,数的正负不影响答案 因此我们全部转化成正数,对于求取无序对,我们枚举每一个数的时候,只要在他两倍内的其他数都可以,因此这个二分求解 #include<bits/stdc++.h> using namespace
阅读全文
摘要:看数据会猜到是区间dp 这道题的精髓就是相同字符才能删除 我们设计状态为删除f[i][j][k],i-j区间,后面有k个相同的在这次删除中一次删除 那么状态转移,最后一位j可以选择和后面的删掉,或者如果区间内有和j相同的字符,可以与k一起被删掉。 两种转移方式,虽然可能更新的时候有很多非法状态,但是
阅读全文
摘要:圆的半径就是三角形中最短边的一半 因此我们枚举所有的边,从大到小维护bitset 如果对于当前边的两点,已经有一个点与他们相连,那么说明这条边就是答案 #include<bits/stdc++.h> typedef long long ll; using namespace std; typedef
阅读全文
摘要:观察式子信息,就能发现原始序列的答案为f[i+1][j]^f[i][j-1]而来 因此维护一下区间最大值之后O(1)输出即可 #include<bits/stdc++.h> typedef long long ll; using namespace std; typedef pair<int,int
阅读全文
摘要:这题动态的难做,因此考虑静态转化,先建成完全的树 之后直接维护,当我们新加入这个点的时候,把这个点的之前权值记录下来 因为这个时候才会被操作影响 #include<bits/stdc++.h> typedef long long ll; using namespace std; typedef pa
阅读全文
摘要:经典套路 动态开点维护质数个线段树,这样我们每次在质数上插入,只要维护一个最小值查询就能知道对于这个质数的最小的那个是谁 因为一个数分解的质数不会太多,主要是数不大,所以做法合理 #include<bits/stdc++.h> typedef long long ll; using namespac
阅读全文
摘要:经典双指针分治法,对于每个i,求出最近的r 但是数据比较大,需要一个离散化 #include<bits/stdc++.h> typedef long long ll; using namespace std; typedef pair<int,int> pll; const int N=1e6+10
阅读全文
摘要:感觉复杂度很有问题的 但是这个算法比较好像,就是先连二分图,从最小权值一直做匹配 数据可能并不是特别强,可能也是确实网络流的算法都是能跑较大数据 #include<bits/stdc++.h> typedef long long ll; using namespace std; typedef pa
阅读全文
摘要:经典填格子问题,这种题都是推出前面的情况后,再不重复的情况求出后面的递推式 因为本题次数大,因此考虑使用矩阵快速幂优化 #include<bits/stdc++.h> typedef long long ll; using namespace std; const int N=30; const i
阅读全文
摘要:朴素的思路就是二维dp,表示上次跳了几个 但是这个存不下,又因为题目提示我们第一次一定是D 因此我们第二维表示上次移动了D+j次,这是因为j只要移动250,就能到达终点,因此可以存下 但是可能是负数,因此我们使用坐标系平移 #include<bits/stdc++.h> using namespac
阅读全文
摘要:先对高度进行排序 之后模拟插入的方法,因为我们要求比自己高的人在前面或者后面有k个 那么如果当给定的k大于n-i那么说明非法,因为只有n-i个空位剩余,做不到要求。 那么接下来我们考虑是前面有k个还是后面有k个,因为我们是按高度来做的,所以对k和n-i-k取个min,使得前面的空位尽可能少,这就是答
阅读全文
摘要:对于这类问题需要掌握nlog求解最长上升子序列的问题 我们发现可以枚举l后的每个点作为删除后的上升子序列的起点。 因为最后的答案肯定以某个点作为起点,因此我们枚举完就能知道答案 因此我们在删除前的一段中二分找到这个点所在的位置,前后相加-1就是当前的答案 对于所有答案取max即可 #include<
阅读全文
摘要:如果直接拓扑建图,那么建图复杂度太高,因此我们考虑线段树优化建图 也就是区间连边,这样也能达到对应的目的,因为是单向边,建一个树即可 之后跑一下拓扑排序 #include<bits/stdc++.h> using namespace std; typedef long long ll; typede
阅读全文
摘要:计数类dp,我们设计状态为以i为根,i所在连通块大小为j的合法方案 枚举他的子树,这条边是否断裂,如果断裂,那么直接乘以子树合法方案,如果不断,那么就是计算贡献 #include<bits/stdc++.h> using namespace std; typedef long long ll; ty
阅读全文
摘要:考虑一个点被使用的奇偶次 这种题如果是边的话,就是经典套路 现在是点,其实可以把他周围的边都计算一遍就知道这个点用了多少次 同时不要忘了加上以他为顶点的n-1条路 #include<bits/stdc++.h> using namespace std; typedef long long ll; t
阅读全文

浙公网安备 33010602011771号