04 2020 档案

摘要:这里我选择了一种在线的树状数组的写法,有三个log,比较好写但是跑的比较慢,吸氧才能过 其实和一维的没有区别,都是整体二分值域的思想 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4e5+ 阅读全文
posted @ 2020-04-29 22:04 朝暮不思 阅读(158) 评论(0) 推荐(0)
摘要:动态修改的整体二分模板,整体二分天然支持修改 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=3e5+10; struct node{ int op,x,y,k,id; }q[N],lq[N 阅读全文
posted @ 2020-04-29 20:32 朝暮不思 阅读(147) 评论(0) 推荐(0)
摘要:这题比较经典,我们想要求比他小的最远的点 因此我们发现,如果一个点比他前面的点大还比他近,说明这个点永远不会作为答案 因此我们就可以维护一个单调队列,之后二分找到第一个大于等于他的位置在哪,之后这个位置的前一个就是答案 #include<bits/stdc++.h> using namespace 阅读全文
posted @ 2020-04-29 16:36 朝暮不思 阅读(219) 评论(0) 推荐(0)
摘要:暴力想法肯定是遍历一遍x的取值范围看看哪个最小,问题就是如何看哪个最小 一个直观的思路是,首先值的变化分为三种,一个是不变,一个是变一个,一个是变两个 不变就是相加为x,那么我们可以想到,能变一个就成说明,我至多变一个的取值范围要包括x,因此只要求一下取值范围就变成了覆盖问题 这种问题可以用差分解决 阅读全文
posted @ 2020-04-29 14:55 朝暮不思 阅读(223) 评论(0) 推荐(0)
摘要:根据题意,本题只关心前缀t是否匹配,而其他位置并不在意 因此我们将题目抽象成将s转转化为t串,其中t串的前m个是指定的,后面的是随意的 又因为s串从头往后并且可以插到两边,自然想到了区间dp,看数据范围也感觉很对,因为区间dp就是向两边扩充 #include<bits/stdc++.h> using 阅读全文
posted @ 2020-04-28 22:53 朝暮不思 阅读(187) 评论(0) 推荐(0)
摘要:这题还有一种做法是整体二分,其实本质上就是权值线段树上二分 另外注意的一点是,负数的时候/2和右移有些许区别。 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; struct 阅读全文
posted @ 2020-04-28 19:48 朝暮不思 阅读(163) 评论(0) 推荐(0)
摘要:这道题很容易看出来二维的转移方程,只要移一下项就行 但是二维的显然不行,这个数据范围,一看就是nlogn的复杂度,因此想到优化,我们看到这个表达式,只能想到是否有四边形不等式优化的可能性 因此去证明一下,因为四边形不等式的决策单调性都是根据min来证的,我们把max取反就变成min,然后根据定理求导 阅读全文
posted @ 2020-04-28 09:07 朝暮不思 阅读(177) 评论(0) 推荐(0)
摘要:首先要知道,三个数离的越近越好,因此我们假设三个数a<=b<=c,之后我们固定b,查找a和c即可 有六种组合,就能遍历所有情况 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4e5+10; 阅读全文
posted @ 2020-04-27 21:03 朝暮不思 阅读(129) 评论(0) 推荐(0)
摘要:牢记法则,正难则反 我刚开始考虑的是从深度深的地方开始算,但是发现,我们是越找深度越浅,但是深度深的答案会被深度浅的影响,这样思考起来很复杂。 因此如果能找到一个从上面往下找的方法就好了,所以考虑先把所有的都当作工业节点,然后转化n-k为旅游节点 首先,旅游节点肯定不是跳跃的,而是连续的,因此如果当 阅读全文
posted @ 2020-04-27 16:01 朝暮不思 阅读(171) 评论(0) 推荐(0)
摘要:11 阅读全文
posted @ 2020-04-27 10:55 朝暮不思 阅读(236) 评论(0) 推荐(0)
摘要:模板题: #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+10; const int mod=1e9+7; struct node{ int l,r,key,mi,rnd,rev,a 阅读全文
posted @ 2020-04-27 08:26 朝暮不思 阅读(201) 评论(0) 推荐(0)
摘要:这道题显然是一个树上问题,题目让我们求到各个点得逆序边最小的点是哪些 我们对于树形dp,一般来说都有一个边上的权值,那么对于本题,我们就要对题目信息进行转化 所以我们不妨把正向边记作0,逆向边记作1,这样我们就能够通过一次dfs来计算到子树中的各个节点需要多少次逆转 我们可以随便挑1作为根节点 那么 阅读全文
posted @ 2020-04-26 16:40 朝暮不思 阅读(120) 评论(0) 推荐(0)
摘要:这道题可以设计状态位前i个,用了j块构造k,取j块中的x块这样的状态 有点01背包的意思,每个钱可取可不取,对于j,x都是如此 对于第二维,我们考虑是否取第i个,而对于第三维,我们考虑在第二维是否取得情况下,第三维是否取 #include<bits/stdc++.h> using namespace 阅读全文
posted @ 2020-04-26 15:52 朝暮不思 阅读(166) 评论(0) 推荐(0)
摘要:这道题的easy版本我写的是n^2*26的,对于这题显然不够用。 我们发现上一题我们遍历了很多重复的情况,因为我们是按位置进行遍历的,所以要全部遍历,这次我们优化一下 我们发现个数最多只有200,因此我们按这个作为枚举对象。进一步发现,因为我们枚举的是a这些数作为两边 那么对于每个数,只需要找到他在 阅读全文
posted @ 2020-04-26 11:07 朝暮不思 阅读(145) 评论(0) 推荐(0)
摘要:这道题数据范围比较小,可以想到一种比较暴力的做法,就是枚举,先用前缀和计算 我们枚举两个端点,将数据分为三段,之后枚举26个字母,就能知道答案是多少 这里有一个小技巧就是,我们在枚举26个字母的时候,就能够算出中间这段的最大值是哪个字母,在这个同时,可以算出两边取哪个更好 #include<bits 阅读全文
posted @ 2020-04-26 10:25 朝暮不思 阅读(180) 评论(0) 推荐(0)
摘要:本题仔细分析发现也是一个二维偏序问题,并且因为强制在线,所以不能用莫队来做,因此考虑分块的做法 这道题,因为题目第一个要求是距离小于半径,因此我们直接算出距离后,通过对距离排序,之后分块 这样的分块就会产生一个性质,在某些块中的所有半径都小于r,而在边界块中,则使用暴力。 在块中我们按质量排序 之后 阅读全文
posted @ 2020-04-25 09:59 朝暮不思 阅读(195) 评论(0) 推荐(0)
摘要:典型的分块例题,和区间众数差不多,本题必须用不带log的做法,因此我们考虑前缀和,因为显然的是,区间中某数的个数都可以用前缀和表示 我们设计一个前缀和表示前i块数j的个数是多少个 然后设计一个d数组表示i-j块之间的答案是多少,这就是分块的基本思想,大块直接维护答案,小块暴力枚举 之后在暴力枚举的时 阅读全文
posted @ 2020-04-24 16:06 朝暮不思 阅读(178) 评论(0) 推荐(0)
摘要:一道经典的分块例题,因为我们通过观察可知,区间众数要不就是中间所有块上的答案,要不就是两边小块上出现过的值 因此我们可以分块处理,只要预处理块与块之间的答案即可,因为本题没有修改操作 另外这题比较卡常,块的大小要先算好,不过也有复杂度更低的算法 #include<algorithm> #includ 阅读全文
posted @ 2020-04-24 08:33 朝暮不思 阅读(169) 评论(0) 推荐(0)
摘要:这道题的思维比较巧妙,考察了异或的性质。 首先我们分析最大的情况,分析这种情况就是要考虑哪些情况两个路径必须相同,那么只有一种情况,就是某一个节点下面有多个叶子节点,因为这样,叶子节点之间只有两条路径,因此这两条路径上的值必须相等。而其他情况的话就可以乱放使得满足题意,因为我们可以选取任意的权值,所 阅读全文
posted @ 2020-04-23 13:54 朝暮不思 阅读(186) 评论(0) 推荐(1)
摘要:这道题本质上是一个二维数点的模板,并且是强制在线的,因此可以用树套树,但是我不会树套树 可以想到一个暴力的方法,就是分块,分完块后,每块动态维护一个vector,因为我们发现,交换两个数后,只有在l-r区间内并且范围在a[l]-a[r]之间的数才会收到影响 这样我们就可以通过vector查找范围 分 阅读全文
posted @ 2020-04-23 10:33 朝暮不思 阅读(227) 评论(0) 推荐(0)
摘要:这道题只需要暴力做即可,注意的是题目有可能给的是大的串包含小的串,比如lo loro这种。因此我们要优先考虑匹配大的 这题我刚开始用了错误的写法,从头遍历给的字符串,如果有匹配就匹配,这是不对的,因为比如这种情况 lo loropo 一旦给的串是loropo ,这样如果先匹配了lo,就没法找到答案 阅读全文
posted @ 2020-04-22 22:04 朝暮不思 阅读(181) 评论(0) 推荐(0)
摘要:模板题 #include<iostream> #include<queue> #include<cstring> using namespace std; const int N=1e5+10; const int inf=0x3f3f3f3f; int dis[N]; int st[N],n,m; 阅读全文
posted @ 2020-04-22 17:27 朝暮不思 阅读(125) 评论(0) 推荐(0)
摘要:比较简单的dp,第一眼的想法肯定直接转移,这样是n^3的复杂度,因此我们需要一些小技巧 仔细观察发现,可以用前缀和来维护答案,这样转移就很快了,只需要找到两个边界点就行 我分了a<b和a>b两种方式讨论,这样比较直观一些。 #include<algorithm> #include<iostream> 阅读全文
posted @ 2020-04-22 15:46 朝暮不思 阅读(149) 评论(0) 推荐(0)
摘要:CDQ分治不但能解决三维偏序问题,还能将某些问题的动态版本变成静态。 比如这题是单点修改,区间查询,这样我们就可以将输入的顺序当作时间轴,之后进行CDQ分治 按x轴排序后,对y进行树状数组加减,这道题就变成了x比他小,并且y也比他小的个数查询 这题还用到了简单的容斥原理,也就是二维前缀和的思想来求取 阅读全文
posted @ 2020-04-22 12:13 朝暮不思 阅读(168) 评论(0) 推荐(0)
摘要:这道题的题意是求 j<i aj<=a0[i] a1[j]<=a[i] 这样的三维上升子序列 发现也是一道三维偏序问题,因此考虑用CDQ分治 对于第一位,我们按照惯例作为时间轴,但是这一次,查询要在前面,因为这里第一位是小于号,所以我们先查询再更改就不会弄到自己 我们将查询的权值设为a0[i],而修改 阅读全文
posted @ 2020-04-21 14:33 朝暮不思 阅读(178) 评论(0) 推荐(0)
摘要:这道题的数位dp是二维的,我们可以把这个问题抽象成在0-S中满足题目条件的两个数的个数,因此可以进行二维的数位dp,从这题我们发现无需记录前缀状态 只需考虑两个flag看是否大于原数,并且两个数不能都是1,而且当i是1,n不能是0. 最后算出的答案并不是全部答案,因为还有i<=j的情况,我们知道这两 阅读全文
posted @ 2020-04-21 08:32 朝暮不思 阅读(602) 评论(0) 推荐(0)
摘要:CDQ分治付出了log的时间代价来使静态的三维偏序问题转化成了二位偏序问题后用用树状数组维护 所谓三位偏序就是a<=a1,b<=b1,c<=c1这种情况,我们将第一维当作时间轴,之后排序来树状数组 这道题是模板题 #include<algorithm> #include<iostream> #inc 阅读全文
posted @ 2020-04-20 21:49 朝暮不思 阅读(125) 评论(0) 推荐(0)
摘要:首先我们发现打的顺序一定是连续的,不然会浪费一次爆炸的机会,比如我打了x 不可能去打 x-1,因为这样x-1的爆炸用不到甚至有可能x-1不会被别的爆炸影响 比如我打了x 不可能直接打 x+2,因为这样x+1的位置最后一定要打但是他打完的爆炸就用不到了 因此我们枚举第一次打的位置,然后计算其他剩下的被 阅读全文
posted @ 2020-04-19 11:23 朝暮不思 阅读(314) 评论(0) 推荐(0)
摘要:这里只需先转化乘二进制后,记录前面有几个0和几个1,并且记录前导0状态,因为前导0会影响答案 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<string 阅读全文
posted @ 2020-04-18 21:32 朝暮不思 阅读(127) 评论(0) 推荐(0)
摘要:这题目最原始的想法我们先对序列排序,发现每个数的贡献其实就是先找到比他小的数的个数记为cnt 然后枚举这个数所在的位置,之后就可以从cnt中选j-1个填到前面,然后还要进行排列 但是这样超过了复杂度,所以我们考虑优化这个组合数表达式,首先是简单的约分 约后,我们发现上下两个阶乘中间的数相减就是一个常 阅读全文
posted @ 2020-04-18 19:31 朝暮不思 阅读(196) 评论(0) 推荐(0)
摘要:这道题的关键是有两个限制,1个是递增,1个是异或 那么如果我们要求递增,则i和i-1的最高位不能相同,因为这样bi就被异或导致失去最高位 因此我们知道最高位相同的数是冲突的,所以我们求取最高位为i的个数是多少个 我们发现答案是 2i 2^(i+1)-1这个区间内的数都可以,那么取值就是取值就是相减+ 阅读全文
posted @ 2020-04-17 22:35 朝暮不思 阅读(220) 评论(0) 推荐(0)
摘要:对于一类构造题来说。都是先找出不能构造的情况,之后再思考构造 在这题当中,如果这个k能够在最小构造次数和最大构造次数之间那就可以构造 现在的问题是如何找到最小和最大。题目说的翻转,我们不如把他看作交换,这样最小的情况其实就是一次交换一次,也就是逆序对的数量 最大的情况就是每次都把所有可以交换的交换掉 阅读全文
posted @ 2020-04-17 11:45 朝暮不思 阅读(149) 评论(0) 推荐(0)
摘要:这道题可以看出与花色无关,甚至与数值无关,我们只需要记住前一个放的值和现在放的不一样就行了 又因为这是一个计数问题,所以我们还要知道前一个值放了之后,有多少种会不符合答案,再算的时候就要去掉他们 因此我们设计状态f[][][][][],表示一张牌,一对牌,三张牌,四张牌同色的个数,然后再枚举一维k表 阅读全文
posted @ 2020-04-16 21:30 朝暮不思 阅读(221) 评论(0) 推荐(0)
摘要:我们想要求某一个真正的序列,很多情况下都是用试填法来求取,填一个数上去看看是否满足条件。 所以我们要知道以如果填当前数,那么以当前数为首的剩下的数和c的关系。所以我们知道要预处理出所有满足条件的数的个数,也就是计数问题。 很自然的,前两位要设计为i个数,第一位,也就是最左边这位填的数是第j大,为什么 阅读全文
posted @ 2020-04-16 20:05 朝暮不思 阅读(190) 评论(0) 推荐(0)
摘要:这道题有意思的地方是,他要求提前决策,不能实时决策,这个意思是,我们不能记录当前点是否成功的状态,而只能记录是否申请的状态。 这道题比较明显的状态是f[][][],前i个,申请了j次,第i个有无申请。 但是我想通过记忆化搜索来做,因此将这个状态设计为前i-1个,申请了j次,第i-1个有无申请。这样初 阅读全文
posted @ 2020-04-16 16:25 朝暮不思 阅读(139) 评论(0) 推荐(0)
摘要:这题很容易想到转移方程式,问题是我们发现第三维如果开2000,会炸 但是我们进一步发现,没必要开2000,因为总共就200个任务,所以背包容量和减少的量的差值最多-200-200 然后平移一下就是0-400.之后就是dfs转移,另外,double类型不要用memset转移 #include<bits 阅读全文
posted @ 2020-04-15 22:17 朝暮不思 阅读(155) 评论(0) 推荐(0)
摘要:这道题要求的是贡献的平均值。 直接计算挺难的,但是我们可以考虑按位枚举贡献,因为最多就30位,现在我们要知道的是,什么是贡献 首先一共有n*n种取法,也就是最后求出来的数要除以n方 那么我们分别来看三个函数的分子是什么,对于每一位,我们都枚举每个数当作右端点,之后寻找合法左端点就行了,这是常用的枚举 阅读全文
posted @ 2020-04-15 20:10 朝暮不思 阅读(200) 评论(0) 推荐(0)
摘要:对于数位dp,很多人有着不同的板子,我也曾经是使用递推板子,后来发现那种方法太过于灵活,对预处理的思维要求很高,因此在这里讲解一下我这种dfs的板子的通法 首先最简单的板子是f[][][],表示处理到了前i位,前缀的状态是什么,以及是不是当前位还是受限于最高位 受限的意思是,比如12345,当我们处 阅读全文
posted @ 2020-04-15 15:55 朝暮不思 阅读(142) 评论(0) 推荐(0)
摘要:根据题目的性质,他要求的子串没有和为0的情况,所谓子串,就是枚举任意一个左端点和右端点的串。我们知道子串的个数是(n+1)*n/2-1(是否为空) 显然超复杂度了,但是我们可以进一步想到,如果只枚举右端点,左端点根据题目的要求变化判断,这种双指针的复杂度,显然只有O(N) 我们又想到,一段区间的和, 阅读全文
posted @ 2020-04-15 14:10 朝暮不思 阅读(156) 评论(0) 推荐(0)
摘要:对于某一类构造题,我们先要找出不符合条件的情况输出-1 之后剩下的都是肯定有答案的 然后我们就开始做这道题目,首先一个想法我们肯定想保证如何不被覆盖 这样我们肯定是想每个点的涂的位置只向后移一位,这样至少一个位置不会被覆盖 但这样我们会发现有可能涂不满,因此我们再用新思路和他结合一下,我们会想到一个 阅读全文
posted @ 2020-04-15 08:48 朝暮不思 阅读(160) 评论(0) 推荐(0)
摘要:一道思维题,我们先找到最大值,因为这个必须要在其中一组中,之后判断两边 注意当最大值在中间的时候有可能是同一组答案 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #inc 阅读全文
posted @ 2020-04-14 22:33 朝暮不思 阅读(145) 评论(0) 推荐(0)
摘要:一道经典的数位dp,我们想要知道各个数分别是多少,不如通过枚举,每次判断一个数。 这题需要判断前导0,我们是否判断前导0的原因就是要看这个0会不会对答案产生影响 这题我们要求0的个数,显然必须判断前导0,例如windy数,前后差值的关系,显然也要判断 但是像数字游戏这类问题就不需要判断,因为不影响 阅读全文
posted @ 2020-04-14 15:01 朝暮不思 阅读(190) 评论(0) 推荐(0)
摘要:这道题需要知道该数是不是数字之和的倍数 数字之和比较好统计,但是有个问题是,每一次进行运算的时候,因为数一直在变化,所以当前数mod数字之和成不成立与之后的没有关系 所以我们考虑枚举模数,因为数字之和本来也没有多大 这样我们只需要在最后判断一下答案就行 #include<iostream> #inc 阅读全文
posted @ 2020-04-14 14:33 朝暮不思 阅读(168) 评论(0) 推荐(1)
摘要:这道题因为要求的是第k大的魔鬼数 所以我们可以采用二分的方法,用k-1来二分,这样就可以找到最左边的>=k的,也就是第k大 之后是数位dp,题目要求的是666,因此我们考虑用两位表示前一位填p1,前前位填p2。剩下的还要保存在这个数之前是否已经存在魔鬼数,这便与边界判断数是否成立,还有一维是老套路, 阅读全文
posted @ 2020-04-14 13:40 朝暮不思 阅读(177) 评论(0) 推荐(0)
摘要:这道题是一道思维+组合计数的题目 题目给了两个操作,我们发现第一个操作并不改变奇偶,但是可以把相同奇偶的数变成同一个数,第二个数可以改变相邻数的奇偶性 这样就是一个经典问题了,问每次改变相邻两个数的奇偶性,能不能将所有的数变成奇偶性相同的。 答案就是,只要在这个区域内,奇数和偶数的个数不都为奇数就行 阅读全文
posted @ 2020-04-14 10:20 朝暮不思 阅读(161) 评论(0) 推荐(0)
摘要:https://blog.csdn.net/weixin_42431507/article/details/105236247 这篇文章非常详细。 我发现,对于构造题,不要给自己添麻烦,能构造出的越简单越好,并且要善于发现题目的性质 题目告诉了我们dp是错的,所以我们要分析一下为什么dp是错误的,然 阅读全文
posted @ 2020-04-13 23:05 朝暮不思 阅读(110) 评论(0) 推荐(0)
摘要:首先根据数据大小发现肯定是不能暴力的,那么我们开始寻找性质 题目要求每k位循环,并且整个序列要是回文,这就说明了一点,那就是每一个循环节都要是回文数。 所以我们现在转化成了求将整个序列的k位变成同一个回文数的最小代价。 我们发现,就可以用贪心的思想,将数分成k组,每组有若干个,每组中的值都要相等并且 阅读全文
posted @ 2020-04-13 23:03 朝暮不思 阅读(306) 评论(0) 推荐(0)
摘要:题目的信息给的很明显,他告诉我们11个数是肯定能够填满这些颜色的 一个方面我们可以通过这个信息来推断题目所问的问题,发现1000以内的数的因子必定有一个在前11个质数之中,这样我们就发现了盲点 即使没有发现这点,我们也可以大胆猜测,直接对每个数进行分解质因数,之后枚举质数涂色,肯定也能得到答案 #i 阅读全文
posted @ 2020-04-13 22:58 朝暮不思 阅读(236) 评论(0) 推荐(0)
摘要:暂时还没有完全领悟这道题的递推写法,先放代码 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<string> #include<vector> using 阅读全文
posted @ 2020-04-12 22:58 朝暮不思 阅读(118) 评论(0) 推荐(0)
摘要:我们遇到数位dp题要求含什么的,都把他转化为不含什么的,这样就跟不要62这道题一模一样了 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<string> 阅读全文
posted @ 2020-04-12 22:26 朝暮不思 阅读(141) 评论(0) 推荐(0)
摘要:最大子矩阵和问题,一般都是用前缀和先计算行,然后枚举行,在列方向做单调队列 这样的复杂度是N^3,对于几百的数据足够了 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #i 阅读全文
posted @ 2020-04-12 15:57 朝暮不思 阅读(162) 评论(0) 推荐(0)
摘要:这种题肯定不会是暴力枚举,多半考虑是贡献 首先我们要想清楚的是,我每次操作,会对哪些节点产生影响,答案又是从哪些节点更新而来 很显然我们会从儿子,自身,父亲这三个角度去思考问题。 所以我们会设计状态 now[]表示自身被操作的次数,a[],表示被儿子影响的次数,b[]表示的是被孙子操作的次数,in[ 阅读全文
posted @ 2020-04-12 09:42 朝暮不思 阅读(163) 评论(0) 推荐(0)
摘要:首先发掘题目性质,题目要求,每个点,要不往左要不往右跳x 因此我们可能先想到排序,之后初始化答案为a[n]-a[1] 那么接下来考虑使用贪心的想法,首先,在接下来的情况左边界肯定不会往左挑,有边界肯定不会往右跳 而且我们要使左边界尽可能大,右边界尽可能小。所以枚举每个点的跳跃情况时,就找一下左右边界 阅读全文
posted @ 2020-04-11 20:32 朝暮不思 阅读(112) 评论(0) 推荐(0)
摘要:这道题目思维量还是挺大的,因为这道题也是维护集合关系,所以我们想到用并查集去维护。 我们应该想到的是,用map映射一下位置,因为原来的数据比较大,不宜维护并查集关系,并且设计两个原点 0 和n+1,表示ab集合,这招是常见手段,因为这两个点是特殊的。之前有到异或并查集也是设计一个另外的原点 又因为x 阅读全文
posted @ 2020-04-11 19:27 朝暮不思 阅读(193) 评论(0) 推荐(0)
摘要:对于异或的题目,很多都跟前缀和放在一起,比如说这题,让你求不相交区间异或值相等的个数 很容易想到用前缀和表示区间,现在考虑如何做到不相交并且不重复计算 1.二维循环,第一维从1开始,第二维一个用来统计,一个用来更新 统计的时候,从i开始到n,把这段里面的所有区间的异或值,都看看前面有没有相等的,之后 阅读全文
posted @ 2020-04-11 14:38 朝暮不思 阅读(159) 评论(0) 推荐(0)
摘要:简单的贪心Trie思路,只要发现异或和路径就是两个到根节点的路径的异或值就行,之后Trie树贪心 #include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #include<queu 阅读全文
posted @ 2020-04-10 22:49 朝暮不思 阅读(211) 评论(0) 推荐(0)
摘要:这题其实就是后缀相同的对数,我们可以倒序插入到Trie树中,之后贪心的选前缀长的,之后再选前缀小的,这样比较好用dfs操作 #include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> 阅读全文
posted @ 2020-04-10 22:07 朝暮不思 阅读(216) 评论(0) 推荐(0)
摘要:这题的思路并不难,但是非常难做对,因为取模太恶心了,随时随地会溢出,并且因为取模的级别低,所以要多框括号防止先乘了再取模,还是会溢出 总之所有地方都取模,并且c++的模数可能是负数,所以需要手写一个mod,防止变成负数。 做法本身就是一个数位dp,这里要求平方和,我们之前一般做的都是求个数,按照求个 阅读全文
posted @ 2020-04-10 19:50 朝暮不思 阅读(190) 评论(0) 推荐(0)
摘要:这道题的意思是给你n个物品,每个物品需要获得c个,单次这个物品获得的概率是p,问你最多有x次机会 能够获得完这些物品的总概率是多少 那么我么可以根据这道题推出状态的情况 前i个物品用j次机会获得概率 这样我们走两层循环就行,因为每次这个物品只有这次机会选中和没被这次机会选中两种可能 所以根据这个情况 阅读全文
posted @ 2020-04-09 22:29 朝暮不思 阅读(168) 评论(0) 推荐(0)
摘要:只需要进行拓扑排序求一下路径总数就可以 但是我在求第二问的时候被坑了,因为我是求完之后枚举判断f[i]也就是到这个点的路径是否为0来判断是否到达 但是忽略了一种极端情况,也就是当次数是模数的整数倍的时候,答案经过取余后等于0,但这其实是已经到达了的 太坑了,刚开始真的没想到。 #include<io 阅读全文
posted @ 2020-04-08 22:45 朝暮不思 阅读(161) 评论(0) 推荐(0)
摘要:这道题我们发现数据范围并不大,而且最重要的一点是,可以看的出区间dp的影子,也就是说长区间的最大值,完全可以通过两个小区间合并而来 因此我们考虑先暴力枚举每个区间的lis。之后进行区间dp计算 有几个注意点是,初始化的时候,只需要初始化长度至少为1的情况,在区间dp内部,有一步赋值操作 这一步的意义 阅读全文
posted @ 2020-04-08 22:38 朝暮不思 阅读(227) 评论(0) 推荐(0)
摘要:依旧是数位dp问题,这里只需要预处理dp数组为前i位,当前位填j的合法方案有多少种, 然后套数位dp的板子就行 #include<iostream> #include<vector> using namespace std; const int N=10; int f[N][10]; int n,m 阅读全文
posted @ 2020-04-08 15:38 朝暮不思 阅读(112) 评论(0) 推荐(0)
摘要:y总的数位dp板子有点东西的,没有用记忆化搜索这东西。这题还是套板子,因为是模数,所以我们还是考虑建立状态为f[][][],表示前i个,最高位填j,模为k的值 #include<iostream> #include<vector> #include<algorithm> #include<cstri 阅读全文
posted @ 2020-04-08 15:08 朝暮不思 阅读(217) 评论(0) 推荐(0)
摘要:这道题和其他最短路问题相比多了一个互相转换的关系,其实也没什么区别,只是做一下多维的情况,将每个城市的四个交通工具设为4个点。 也就是说普通最短路一个点代表一个城市,而现在是每个城市的四种交通工具都代表一个点,这样其实只是需要用map映射一下关系就行 另外的就是,因为起点和终点都有多种可能,也就是多 阅读全文
posted @ 2020-04-07 22:55 朝暮不思 阅读(160) 评论(0) 推荐(0)
摘要:这道题,对于小数据,直接上爆搜,也就是把每个点所有能到的地方都用vector存一下,当0的时候,任意选点,之后再从所有能到的地方选点。因为第一问数据非常小,所以算法合格 但是第二问数据比较大,可以采用贪心算法(没有证明正确性,但是跑过了所有数据),在上面的前提下,每次选点都从合法范围最大的点出发 从 阅读全文
posted @ 2020-04-07 15:45 朝暮不思 阅读(200) 评论(0) 推荐(0)
摘要:这题要求不含前导零,所以我们要对有前导0的数,进行枚举一遍 前两题之所以可以用含前导零的来直接做,是因为不影响答案,比如度的数量,第一位选0没有问题 又比如不降数问题,即使有前导0,也不影响答案,所以可以不处理 但是对于windy数,会影响答案,比如一个数0135,按道理是135是符合答案的,但是加 阅读全文
posted @ 2020-04-06 22:02 朝暮不思 阅读(145) 评论(0) 推荐(0)
摘要:同样的套路,这题求的是不降数,只需要在预处理的时候处理一下就行 #include<iostream> #include<vector> using namespace std; const int N=17; int f[N][N]; int n,m; void init(){ int i,j; f 阅读全文
posted @ 2020-04-06 21:22 朝暮不思 阅读(210) 评论(0) 推荐(0)
摘要:对于数位dp的题目,我学习的是y总的模板,也就是说把所有数先用拆位后考虑从头开始考虑,形成一个树的形状 左分支为填0-ai-1的情况,这列情况一般可以通过数学公式一次性求出,之后右分支就填当前数,这样向下延申,在最后特判右分支的情况,也就是一个数 对于数位dp,一般存储两个量,一个是个数,一个是la 阅读全文
posted @ 2020-04-06 20:38 朝暮不思 阅读(330) 评论(0) 推荐(0)
摘要:这道题首先我们要发现的一个性质是,不过从是从后面取上来,还是从前面放到后面,当我们把想要的数字输出之后,序列是不变的,不信可以试试 这个是关键点,因此,我们只要考虑哪种情况小就取哪种情况就行了,不用考虑顺序问题。 之后还有一个问题是,如果快速求取花费值,我们进一步发现,这里的求值,永远是一段一段求的 阅读全文
posted @ 2020-04-06 17:27 朝暮不思 阅读(215) 评论(0) 推荐(0)
摘要:这是经典的谷歌面试题,也是经典的动态规划问题 根据y总的说法,动态规划问题要划分集合,表示状态 对于这道题,有两个经典的解法,他们的复杂度不同,因为对状态的定义略有不同 1.最常规的思想,设计状态为前i层用j个鸡蛋所能测的最坏情况的最小值是多少 我相信集合的定义很多人能想到,但是状态的定义还需要进行 阅读全文
posted @ 2020-04-06 11:08 朝暮不思 阅读(306) 评论(0) 推荐(0)
摘要:一个经典的通过增长减小大小来求使得序列单调性的最小代价。 对于这道题,有一个前置题是不要求要严格单调,而是不严格单调 这样的话,我们可以得到一个性质,最后所有的值都是在原序列当中的,这其实用贪心的想法想一想就好,因为一旦通过加减与左边或右边相等,就没必要再加减了 但是本题要求严格,这就很难说了,因此 阅读全文
posted @ 2020-04-05 17:38 朝暮不思 阅读(310) 评论(0) 推荐(0)
摘要:题目吓死人系列,这一串浮点位置看哭我,后来仔细读题,发现题目问的是,最少经过多少次移动能将序列排成非严格单调递增 为什么是这样的呢,因为他想要分m个区域,并且要求每个i种类都位于i区域,那么只能把所有的排成非严格递增才行 那这道题就简单了,其实就是求LIS,之后用总数减一下就行,这里我使用的是nlo 阅读全文
posted @ 2020-04-05 15:35 朝暮不思 阅读(185) 评论(0) 推荐(0)
摘要:这题的主要信息就是,这是一个排列,而不是数列 对于排列也就是说每行都是1-n这些数,只是位置不同,我们观察到n只有1000 并且考虑到对于一个最长公共子序列,也就是说,如果两个数能成为公共子序列,那么其中一个数在每一行都是在另一个数后面 所以我们设计dp状态f[i]表示以i结尾的最长公共子序列,在转 阅读全文
posted @ 2020-04-05 14:54 朝暮不思 阅读(177) 评论(0) 推荐(0)
摘要:一般对于这种dp,都会设计两维,表示a中前i个和b中前j个能表示的最长长度是多少 那么考虑对集合进行划分 我们可以想到,当遍历到i,j时,有四种可能,一种是都不选,一种是都选,还有两种是选一个 对于都不选,那么就等于f[i-1][j-1],对于都选,是f[i-1][j-1]+1,前提是相等 剩下两种 阅读全文
posted @ 2020-04-05 13:59 朝暮不思 阅读(135) 评论(0) 推荐(0)
摘要:典型的拓扑序来求最小花费 然后满足花费的判断最大值 存路径一般都是用一个数组来存,老套路了 拓扑在DAG上真的好用 #include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algorithm> #inc 阅读全文
posted @ 2020-04-04 20:28 朝暮不思 阅读(250) 评论(0) 推荐(0)
摘要:如果想要判定是否是DAG,用拓扑排序是一个好选择,但是本题可以删一条边 如果真的傻傻的去枚举删边就难顶了 我们要想到,对于删边,其实就是入度-1,而我们知道,删完能拓扑,说明成功了,因此只要枚举点,对入度操作再跑拓扑,就能AC 这个转化还是很有意思的,我们来思考正确性,首先对于一个环,肯定因为到了某 阅读全文
posted @ 2020-04-04 19:54 朝暮不思 阅读(210) 评论(0) 推荐(1)
摘要:在DAG上用拓扑排序求最长最短路似乎十分常见,我在做一道cf的题目时无意间看到这题 这题要求的是最长路,因此用拓扑序来求,为什么可以用拓扑序呢? 因为我们对于每个点,都会跟他相连的点被更新,因此就可以通过max操作,直到所有点被更新完,才会将他入队,那么这个点的最终值也就被确定 #include<i 阅读全文
posted @ 2020-04-04 18:39 朝暮不思 阅读(150) 评论(0) 推荐(0)
摘要:这道题本质上就是找左右边第一个比他小的数在哪,作为他的边界 因为数据范围比较大,所以我们考虑用到单调栈来写 可以先求左边,再反转数组重求,也可以直接到着求右边 如果反转数组,那么就要注意最后相减的表达式 #include<iostream> #include<cstring> #include<cs 阅读全文
posted @ 2020-04-04 15:37 朝暮不思 阅读(168) 评论(0) 推荐(0)
摘要:本题比较简单,就是线段树的几个基本操作,而素数,我们自然想到用素数筛筛一下后直接判定即可 这里有几个小坑点,在单点更新的时候也需要pushdown,因为区间更新可能会影响到最后节点的值 另外按照我的写法,我把lazy和数值分开表示,所以在pushdown的时候要特判是否到了叶子,如果到了,num也需 阅读全文
posted @ 2020-04-04 11:35 朝暮不思 阅读(148) 评论(0) 推荐(0)
摘要:这道题乍一看是最长上升子序列(其实也是) 但是这里要求是+1的最长上升子序列,我们自然想到由dp[a[i]-1]+1转移过来。但是很坑的是这个数据很大 有1e9,我当时还以为有什么精妙的解法,没想到是利用map进行映射。既然数组存不下,那就用存的下的去存 只要遍历map找到最大的,之后倒着枚举就行了 阅读全文
posted @ 2020-04-03 21:37 朝暮不思 阅读(187) 评论(0) 推荐(0)
摘要:这道题暴力没办法做,所以要从题目式子找性质,我们发现,分母的大小最多不会超过30,而我们要求的是一个和,所以想到对分母相同的数进行前缀处理 这样求和很快,也就是说,我们进行预处理,把这些数的30个分母情况都列举一遍,而求的时候,利用二分判断分母的位置,所以在开始前先对a数组排序,就变成了一段一段求和 阅读全文
posted @ 2020-04-03 16:42 朝暮不思 阅读(173) 评论(0) 推荐(0)
摘要:dp问题的状态设计都是十分巧妙,根据y总的说法,可以把他看作集合,对于转移,考虑最后一个不同量/ 对于dp状态,首先要观察题目的信息,看他有什么,我认为所有的dp的状态都能从题目中猜出来,这题目告诉你括号可以移动。 我们进一步发现,左括号只能与右括号相换,所以所有左括号的相对顺序是不变的,同理右括号 阅读全文
posted @ 2020-04-03 10:49 朝暮不思 阅读(193) 评论(0) 推荐(1)
摘要:这道题是最长上升子序列求方案数的题目 对于这种题目,需要多几个变量,一个是前置,一个是当前id 因为我们肯定想到要对他进行排序 在求方案数的时候只需要从末端一直往前缀走就行,直到-1 这题因为前提要大于这个信,所以在输入时需要判断一下 #include<iostream> #include<cstr 阅读全文
posted @ 2020-04-02 15:11 朝暮不思 阅读(152) 评论(0) 推荐(0)
摘要:一看数据范围很小,直接暴力搜索判断,枚举m位看能否满足条件,递归的时候分奇偶,因为每次加的方向不一样,之后比对一下是否相同以及是否比他大 #include<iostream> #include<cstring> #include<cstdio> #include<map> #include<algo 阅读全文
posted @ 2020-04-02 14:20 朝暮不思 阅读(185) 评论(0) 推荐(0)
摘要:1.首先明确这道题想要求取的是在l-r中新认识的人的对数 如果想要知道新认识的人是多少,那么我们可能会考虑到上次认识的人的左右边界。并且可以想象到的是,在一个区间中,右边的人新认识的左边的人,其实就是左边的人新认识的右边的人 如果重复的计算,那么最后要/2。所以我们可以直接考虑有边界 2.有一个性质 阅读全文
posted @ 2020-04-01 22:38 朝暮不思 阅读(159) 评论(0) 推荐(0)
摘要:查询三元的等比数列,数据范围是2*1e5,想到应该是扫一遍就够了 其实就是找x/k和x/k/k 这些组合,所以想到用map来存 设计两个map,一个是用来存出现的个数,一个用来存,x和x/k这样组合的总个数,这样查找的时候就非常方便。 #include<iostream> #include<cstr 阅读全文
posted @ 2020-04-01 15:37 朝暮不思 阅读(215) 评论(0) 推荐(1)
摘要:看到01串计算长度,显然是前缀和,进行贡献转化,把0看成-1,再用map 但是我犯了个错误,我虽然存了0这个位置,但是因为0的位置是0,我在后面使用m1[sum]来查找,其实是查不到的,所以要用count函数来找 #include<iostream> #include<cstring> #inclu 阅读全文
posted @ 2020-04-01 11:54 朝暮不思 阅读(144) 评论(0) 推荐(0)