10 2020 档案

摘要:这道题求取的本质是二进制不进位加法的队数,因此模型比较常见,因为我们不太会维护有下界的数位dp 所以往往使用容斥原理变成无下界的dp #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll, 阅读全文
posted @ 2020-10-30 23:12 朝暮不思 阅读(125) 评论(0) 推荐(0)
摘要:常规做法,看出是破环成链后用哈希维护,只要枚举前k位,之后往后跳n次,看看是不是都有满足条件的字符串 注意,每个字符串只能用一次,因此还需要额外维护一个map表示是否已经使用 cf的数据比较强,卡了单哈希也卡了加法双哈希,因此用pll维护哈希即可 #include<bits/stdc++.h> us 阅读全文
posted @ 2020-10-30 18:12 朝暮不思 阅读(121) 评论(0) 推荐(0)
摘要:https://zhuanlan.zhihu.com/p/268630329 在知乎上有位网友总结出来一种贪心套路 这题的本质上是对于每对数,要将ai放入A集合或者把bi放入B集合 最后求min(MAX(A)+MAX(B)),因此采用排序后,保留合适的值 之后枚举每种可能答案即可 #include< 阅读全文
posted @ 2020-10-30 15:20 朝暮不思 阅读(130) 评论(0) 推荐(0)
摘要:暴力的做法就是枚举每一位选什么,但是过于暴力,我们只需要记忆化搜索一下,表示之后的有没有算过即可 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5e5+10; const int mod= 阅读全文
posted @ 2020-10-30 10:34 朝暮不思 阅读(77) 评论(0) 推荐(0)
摘要:多模式串匹配问题,因为要求每个串不重复出现的次数,我们只需要对于每个串维护一个len,如果匹配到当前串的末尾并且到之前匹配的长度大于等于len,那么说明是新的答案 我采用的方法是对于每个独立串的末尾标记一下,这样我们去做自动机的时候就能够知道是否匹配,但是每次都要走到根,因为这样才可以覆盖到所有的串 阅读全文
posted @ 2020-10-29 23:41 朝暮不思 阅读(138) 评论(0) 推荐(1)
摘要:本题难想的是状态设计,因为要做到不重不漏,所以我们设计状态为f[i][j]表示以i为根,子树中到i点最大距离为j的方案数。 那么在更新的时候,只要根据新的子树和之前所有的子树的关系即可更新,因为很多j都可以成为答案,如果再枚举一维就会超过复杂度 因此使用前缀和优化,来降维到二维dp #include 阅读全文
posted @ 2020-10-29 20:29 朝暮不思 阅读(175) 评论(0) 推荐(0)
摘要:比较容易看的出来的是这题求得是最小公倍数的最大值 然后我们可以发现一定是选不同质数的次幂,因此每个质数的次幂就是一个集合,因此只需要跑一下分组背包就可以了 #include<bits/stdc++.h> using namespace std; typedef long long ll; const 阅读全文
posted @ 2020-10-29 09:16 朝暮不思 阅读(124) 评论(0) 推荐(0)
摘要:如果没有取模,直接维护线段树哈希,原理跟普通哈希是相同的,就是维护一个哈希数组 本题有取模操作,其实有一个常见的套路就是我们发现取模的次数并不会太多,因此对最大值超过限制的区间直接暴力取模变成0,这样复杂度还是可以过关的 #include<bits/stdc++.h> using namespace 阅读全文
posted @ 2020-10-28 21:06 朝暮不思 阅读(252) 评论(0) 推荐(0)
摘要:对于这个dp转移方程,我们观察到的是每个点都从左上方转移或者上方转移。 如果从左上方转移,那么多了一个b[i],可见我们对于每一行在第几列,就能获得几个b[i],那么这其实就是求区间的前k大值和 这就是主席树模板题 #include<bits/stdc++.h> using namespace st 阅读全文
posted @ 2020-10-26 15:56 朝暮不思 阅读(495) 评论(0) 推荐(0)
摘要:套路题,对于步长大于根号n的,直接暴力做,对于步长小于根号n的,保留离线后 对于每个步长for一遍,这样复杂度也是n*根号n #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int 阅读全文
posted @ 2020-10-25 18:14 朝暮不思 阅读(142) 评论(0) 推荐(0)
摘要:这道题的原理是普通的二维差分和二维前缀和,但是因为不能开二维数组,因此映射到一维就行 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e7+10; const int mod=1e9+7; 阅读全文
posted @ 2020-10-24 16:01 朝暮不思 阅读(160) 评论(0) 推荐(0)
摘要:线段树题目,维护的信息非常对。 因为我们看到的是区间修改和区间查询,所以可以想到用线段树 现在的要求是往前后插数,求的是数的和。 因此我们可以考虑维护lazy标记往前插的数,往后插的数,和插的位数 并且还要维护答案sum1,以及区间的长度sum2,这是因为区间的长度是不定的,而我们维护区间和的时候, 阅读全文
posted @ 2020-10-24 12:49 朝暮不思 阅读(104) 评论(0) 推荐(0)
摘要:这题精妙的一点就是将通过把性质(最多一位是奇数)转化成前缀和异或和,之后任意两点之间的数量就是异或值。 这样我们把每条边的权值都当成1<<i即可。因为我们要对每个点计算答案,所以需要用树上启发式合并,也就是保留重儿子,遍历所有其他节点。 对于一个点的答案,他有三个来源,1是直接子树中的答案,2是以u 阅读全文
posted @ 2020-10-24 10:07 朝暮不思 阅读(111) 评论(0) 推荐(0)
摘要:一个经典套路是异或前缀和公式,因此我们可以枚举右端点,寻找异或值大于等于k的答案 做完后每次把前缀和放到trie树上面去。 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1000005; 阅读全文
posted @ 2020-10-22 19:49 朝暮不思 阅读(110) 评论(0) 推荐(0)
摘要:题目要求的是分组后的组间最大值-最小值的最小是多少。 因为我们发现有两个变量,因此很难做,一种经典思路就是固定一个答案,然后求相对于这个答案的另一个值的最优解,枚举所有情况取min即可。 对于本题,我们发现所有的值其实已经明了,因此先预处理计算后,我们可以枚举最小值,之后找到满足条件的最小的最大值。 阅读全文
posted @ 2020-10-22 18:01 朝暮不思 阅读(191) 评论(0) 推荐(0)
摘要:C 分类讨论+思路 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+10; string s,t; int a[N]; vector<int> num; #define mp mak 阅读全文
posted @ 2020-10-21 22:55 朝暮不思 阅读(196) 评论(0) 推荐(0)
摘要:模拟退火模板,按比例接受 #include<bits/stdc++.h> using namespace std; const int N=1e5+10; const double eps=1e-8; double ans; double y; double cal(double x){return 阅读全文
posted @ 2020-10-20 23:27 朝暮不思 阅读(98) 评论(0) 推荐(0)
摘要:对于暴力dp来说,对于当前i位置分成j段的答案就是f[l][j-1]+val(l+1,i),对于所有符合条件的答案取一个max 我们发现暴力会t,并且是取max,想到用线段树维护前一次的dp,这样只要dpk次就能获得答案。 至于val,其实就是区间修改,对于每个点,他有贡献的区间就是离他相同最近的点 阅读全文
posted @ 2020-10-20 22:28 朝暮不思 阅读(115) 评论(0) 推荐(0)
摘要:一个子树的重心一定是在子树的重儿子与当前根的路径上 #include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=1e6+10; int h[N],ne[N],e[N],idx; int ans[ 阅读全文
posted @ 2020-10-19 23:38 朝暮不思 阅读(170) 评论(0) 推荐(0)
摘要:A题 莽结论,注意特判0 #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=1e5+10; int main(){ ll n,k; cin 阅读全文
posted @ 2020-10-19 22:01 朝暮不思 阅读(217) 评论(0) 推荐(0)
摘要:本题首先告诉我们,初始的树是符合条件的 我们考虑如何构造出一种正确答案。 如果一个边可以删除,说明这个边的两端点在删除边之后仍然能够满足题目的要求,因此我们可以看出,在理想的情况下,最多也只能删除k-1条边 因为我们至多只能有k个孤立集合,前提是每个集合里面都有一个警察局。 发现了这个点之后,可以感 阅读全文
posted @ 2020-10-16 11:42 朝暮不思 阅读(134) 评论(0) 推荐(0)
摘要:对于这种题目,基本上都是先枚举后维护信息。 自然的想到从小到大枚举横边或竖边,之后维护另一种边。 因为要区间计数,所以考虑树状数组,只要满足边穿过枚举边的都可以加入。 在固定最低边后往后枚举,计算组合数,并且注意删除不满足题意的边 #include<bits/stdc++.h> using name 阅读全文
posted @ 2020-10-15 23:18 朝暮不思 阅读(130) 评论(0) 推荐(0)
摘要:这题十分巧妙的就是对模型的转换。题目给的条件是相邻两个是朋友的物种可以互换。 那么我们发现,我们进行建图,对于我们前面的,如果是自己同一物种的,那么没必要交换 如果是不同物种且不是朋友的,我们没法超越他,这样产生了一个拓扑序。 因为对于前面没有约束的,只需要找到一个字典序最小的输出即可。所以我们设计 阅读全文
posted @ 2020-10-14 22:40 朝暮不思 阅读(184) 评论(0) 推荐(0)
摘要:A题 带限制的最短路 #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; int h[N],ne[N],e[N],d[N], 阅读全文
posted @ 2020-10-14 21:51 朝暮不思 阅读(280) 评论(0) 推荐(0)
摘要:本题的重要信息就是最大公约数一定是大于等于一半的a[i]拥有的,也就是说我每次随机取一个,会有50%的机会选中正确答案。 这样我只有随机化多次,就能在极大概率上获得正解。 对于一次随机化,找到所有的约数,之后用最大公约数公式找到最大的能满足条件的答案。 #include<bits/stdc++.h> 阅读全文
posted @ 2020-10-13 20:29 朝暮不思 阅读(128) 评论(0) 推荐(0)
摘要:答案就是就是区间没有覆盖的长度 有一个直接的想法就是我们发现能够通过推倒建立起来的关系就是一个集合,也就是用并查集缩点,那么之后只需要维护一个后缀和就能做 因为我们不可以将前面的询问影响到后面的答案,因此考虑倒序做。 可以考虑维护一个栈,不断合并能够合并的点,这样后缀和就是栈顶第一个没被合并的点的后 阅读全文
posted @ 2020-10-13 12:00 朝暮不思 阅读(136) 评论(0) 推荐(0)
摘要:首先本题的信息很少,只有一个删除节点求期望。 那么我们只能从有限的信息中找答案,因为他删除一个点就会删除整个子树 因此我们可以联想到对于这个题是否要考虑父亲和孩子的关系。 首先我们要知道这题的期望是怎么计算的,因为期望代表的是天数,定义f[i]为点i是否被删除,因此我们的期望就是删除的个数的期望 根 阅读全文
posted @ 2020-10-12 21:59 朝暮不思 阅读(87) 评论(0) 推荐(0)
摘要:思维题,对于曼哈顿距离,很多时候都是把绝对值拆开,我们发现,对于两个点一定是一正一负取大的,我们发现这就是对立的两种情况 进一步发现k只有5个,很容易联想到状压,因此我们对于最大的曼哈顿距离就是两个状态的和,他们的各个位仅有一个1并且总和有k个1 接下来我们只需要维护一个区间最大值,这可以使用线段树 阅读全文
posted @ 2020-10-12 19:42 朝暮不思 阅读(118) 评论(0) 推荐(0)
摘要:本题容易看出分层的样子 对于i-1来更新i的答案。我们对于更新有两种选择,一种是直接枚举点对更新,一种是用spfa进行o(N*M)更新 我们发现对于两种情况的最坏复杂度情况不同,因此可以进行讨论选择使用哪一种更新、 #include<bits/stdc++.h> using namespace st 阅读全文
posted @ 2020-10-11 20:24 朝暮不思 阅读(235) 评论(0) 推荐(0)
摘要:计算一些数的平均数是否等于一个数,可以等价于将这些数-这个数后计算和是否为0,这样我们可以避免除法运算 为了避免负数,我们将初始可能值-n后+1000,这样只需要知道1000这个位置有没有达到即可。 对于如何扩展,我们对于每个数,都枚举所有能够对他产生贡献的数,并且避免重复的数出现,这样的复杂度是平 阅读全文
posted @ 2020-10-10 23:41 朝暮不思 阅读(156) 评论(1) 推荐(0)
摘要:思路的转换还是比较重要。 虽然本题有两个条件需要控制,但是我们发现第一个条件是根据输入顺序来的,那么就会产生一个猜想,如果边输边做,那么只需要维护第二个条件就可以了。 第二个条件是权值为递增,这个非常像dp中的最长上升子串,但是由于本题是图,所以不能用dp方程做,但是可以借鉴一下。 我们在做dp的时 阅读全文
posted @ 2020-10-10 19:59 朝暮不思 阅读(166) 评论(0) 推荐(0)
摘要:题目告诉我们连通块是一次染色的,因此我们将所有连通块缩点,这样树就变成了黑白相间且与原答案一样的树 对于这种树,我们采用贪心的策略,从树直径不断往外染色,那么染完直径就是答案。 这是因为我们直径上要黑白相间的染,这样对于其他的分支,也会不断地改变,当我们染完直径,其他不可能有比他更长的没被染色 并且 阅读全文
posted @ 2020-10-09 23:01 朝暮不思 阅读(133) 评论(0) 推荐(0)
摘要:显然质数越小越好,越小的质数次方越大越好,写个dfs爆搜一下 #include<bits/stdc++.h> using namespace std; typedef unsigned long long ll; const int N=4e5+10; const int inf=0x3f3f3f3 阅读全文
posted @ 2020-10-09 15:43 朝暮不思 阅读(78) 评论(0) 推荐(0)
摘要:当不存在没有被染色的边时: 若被自己染黑,则由于规则 1,这个点染了以后所有儿子都会被染 色,因此儿子的情况可以随便选: fu,1,0 = 1 + ∑min{fv,0/1/2,0/1} 若被儿子染黑,则必须要选择一个儿子传递上去,儿子能传递上 来只有两种情况: fu,0,0 = minv{min{f 阅读全文
posted @ 2020-10-08 11:37 朝暮不思 阅读(197) 评论(0) 推荐(0)
摘要:这个题有一个限制条件,就是每个位置会有d个怪物,题目告诉我们他会挡住d条路,并且要我们计算在最坏情况下的最短路。 最坏情况,就是阻挡我到达这个点之后,往外的前d小的路。因此这是一个多元变种迪杰斯特拉,在普通的多元迪杰斯特拉的情况 我们注意每个点的d状态,忽视前d个到达这个点的答案,这样跑出来的就是最 阅读全文
posted @ 2020-10-08 09:41 朝暮不思 阅读(190) 评论(0) 推荐(0)
摘要:A 数位dp B 欧拉路径判定 #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=500005; const int inf=0x3f3f 阅读全文
posted @ 2020-10-07 23:06 朝暮不思 阅读(420) 评论(0) 推荐(0)
摘要:思维好题 首先考虑哪些状态下所有答案均为0,一种是,对于某一个点的邻边,存在三个相同的数,或者存在aabb形的数,因为我们无论以哪个点为根,这个点一定有两个作为他的儿子,所以上述情况都不满足。 在特判过后,我们寻找哪些可能满足条件,考虑进行dfs序遍历,对于每个点的dfs序和在他邻边中两个相等的边所 阅读全文
posted @ 2020-10-07 23:03 朝暮不思 阅读(230) 评论(0) 推荐(0)
摘要:对于本题,本质上是哈密顿回路,但是由于特殊性,每个点仅有一条往外的连边 因此,本题等价于欧拉路径的判断,只需要根据欧拉路径判断答案即可 即连通性和出度入度间的关系 #include<bits/stdc++.h> using namespace std; typedef long long ll; t 阅读全文
posted @ 2020-10-07 20:25 朝暮不思 阅读(203) 评论(0) 推荐(0)
摘要:正难则反。动态加边比较难以维护,考虑倒着维护 先把全部边都添加的状态维护好,之后倒着删边。 对于每一次,如果有一个人他没有k个好友,那么他就永远不可能旅游,因此将他删除后,并且用一个队列来做因为他删除而导致的一系列后果。 那么还在的人是都可以去旅游的,因为他们都有k个好友 因此我们每次删一条边就把两 阅读全文
posted @ 2020-10-06 09:58 朝暮不思 阅读(126) 评论(0) 推荐(0)
摘要:A题 模拟 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod1=1e9+7; const int mod2=1e9+9; int base=11; struct X{ int x,y; i 阅读全文
posted @ 2020-10-05 22:03 朝暮不思 阅读(397) 评论(0) 推荐(0)
摘要:将图的所有状态都存下来,一步一步bfs遍历,但是需要去重,由于重载运算符过于复杂,因此考虑用双哈希去重 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod1=1e9+7; const int 阅读全文
posted @ 2020-10-05 21:59 朝暮不思 阅读(270) 评论(0) 推荐(0)
摘要:观察到所有成环的之间的距离都是1,因此可以想到使用tarjan缩点后建立园方树 这样答案就是两点间距离/2 #include<bits/stdc++.h> using namespace std; typedef pair<int,int> pll; const int N=1e6+10; int 阅读全文
posted @ 2020-10-05 10:27 朝暮不思 阅读(159) 评论(0) 推荐(0)
摘要:对于这些运算,我们考虑一个问题。对于叶子取反,因为每次只对一个叶子节点操作,一般来说,他的父亲节点会反转,只有存在以下情况不会反转 1.or运算且有一个儿子是1,那么另一个儿子无论怎么操作都是1 2.and运算,如果一个儿子是0,那么另一个儿子无论怎么操作都是不变化。 #include<bits/s 阅读全文
posted @ 2020-10-04 23:33 朝暮不思 阅读(137) 评论(0) 推荐(0)
摘要:做的时候想到拆点,但是没想到维护关系的方法。 这题我们考虑一个字符串分成原串和相反串,用i和i+n表示,我们要做的是维护所有串的相对关系,也就是选了某些串就要选其他串 考虑任意两个字符串i,j之间的关系,如果他们不反转和一个反转都是满足要求的,那么就不用约束关系 如果不反转和反装都不能满足要求,那么 阅读全文
posted @ 2020-10-04 16:09 朝暮不思 阅读(233) 评论(0) 推荐(0)
摘要:A 映射一下 #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=4e5+10; const int inf=1e9; int a[N]; 阅读全文
posted @ 2020-10-04 11:56 朝暮不思 阅读(133) 评论(0) 推荐(0)
摘要:本题如果去掉怪物选项就是双关键字最短路。 问题是现在多了一个怪物选项,因为这个怪物选项被杀死后他不会复生,因此我们不能重复计算这个值的答案。 所以对于每条过来的路,前面一个点遇到的怪物的后面的点就不用计算了,也就是去重。 根据这个思路,我们可以得到我们想要干的是当枚举到当前点,我们希望计算出他的co 阅读全文
posted @ 2020-10-04 10:56 朝暮不思 阅读(178) 评论(0) 推荐(0)
摘要:根据斐波那契的性质得出,区间存在结合律,因此我们对于原先给定的先建出线段树,对每个点维护一个矩阵表示当前的斐波那契答案。 对于opt1,就是区间修改,也就是加上一个转移矩阵,传递这个矩阵,与普通的线段树操作一样的 对于opt2.也就是区间查询,查询区间内的和,因此我们只需要维护一个sum矩阵和laz 阅读全文
posted @ 2020-10-03 21:40 朝暮不思 阅读(241) 评论(1) 推荐(0)
摘要:本题的k很小,我们发现最多不超过10的点会产生贡献 题目中要求没有奇数环,这让我们想到了二分图染色。 因此答案肯定是所有偶数环的最优解。 因此我们对图上的点随机赋值一种颜色,走所有的偶数环 在重复一定的数量,这样走到正解的概率就很大了 #include<bits/stdc++.h> using na 阅读全文
posted @ 2020-10-03 09:13 朝暮不思 阅读(168) 评论(0) 推荐(0)
摘要:连续两道遇到换根dp。 这道题比较复杂一点,遇到题目我们应该关心的是题目的数据,我们发现k的数据很小,很容易想到可以用mod的状态来控制 如果过了一轮就步数+1,因此还需要维护下面的mod的点数 #include<bits/stdc++.h> using namespace std; typedef 阅读全文
posted @ 2020-10-02 22:12 朝暮不思 阅读(205) 评论(0) 推荐(0)
摘要:刷了这么久终于遇到水题,十分套路的换根dp,先自底向上维护,之后自顶向下维护一遍 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4e5+10; int h[N],e[N],ne[N],id 阅读全文
posted @ 2020-10-02 19:17 朝暮不思 阅读(136) 评论(0) 推荐(0)
摘要:第一点可以想到的是,对于某个位置i上的数,他能不能被删除只和前面的数的能不能删除掉-(a[i]-i)的数有关。前提是他要a[i]-i小于0 现在的问题是,因为他有很多询问,因为左区间的限定,我们对每个询问需要知道每个i对于当前左区间l-i之间能删除多少个数,这样我们才能知道对于当前区间这个点能不能删 阅读全文
posted @ 2020-10-02 14:53 朝暮不思 阅读(162) 评论(0) 推荐(0)
摘要:A 签到 #include<bits/stdc++.h> using namespace std; int a[123456]; int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); int f=0; int t= 阅读全文
posted @ 2020-10-01 17:04 朝暮不思 阅读(227) 评论(0) 推荐(0)
摘要:xz=zy 其实对应的就是把x的某一段前缀减下来贴到后面或者把y的某一段前缀贴下来到前面 如果相等则可以,这点可以在纸上模拟。因为y一直在变,所以我们考虑预处理x 对比字符串是否相等,使用哈希即可,本题使用了双哈希避免被卡。 我们关注到,当我们求得最小能够剪切成功的段时,答案并不是只有这个,因为如果 阅读全文
posted @ 2020-10-01 16:58 朝暮不思 阅读(164) 评论(0) 推荐(0)
摘要:考虑dp,我们知道答案就是逆序对为0的期望步数。 对于一轮操作,有50%的可能逆序对不变,有50%的可能逆序对-2 对于这个状态方程进行化简就能得到答案 #include<bits/stdc++.h> using namespace std; typedef long long ll; typede 阅读全文
posted @ 2020-10-01 11:16 朝暮不思 阅读(115) 评论(0) 推荐(0)
摘要:图中给出了不等式关系并求可行解,考虑使用差分约束来解决。 差分约束的基本套路是: 1.找全不等关系 2.找到一个点可以遍历全图 3.对于可行解问题,跑最短路,一般上我们定义>=关系式 对于本题的关系式,为了控制l<=ai<=r,我们用一个超级点去连 对于fi的限制,有两种情况,前面有和他长度相等的, 阅读全文
posted @ 2020-10-01 09:48 朝暮不思 阅读(118) 评论(0) 推荐(0)