05 2021 档案

摘要:原题链接 考察:数位dp 思路: 定义一个变量st,目前枚举的数字的状态. st==0 跟上位比递减 st==1 跟上位比严格递增 st==2 出现了山峰现象. 如果出现了与上位相等或者之前出现了山峰现象,直接把状态传递下去. Code #include <iostream> #include <c 阅读全文
posted @ 2021-05-31 12:00 acmloser 阅读(41) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 思路: 预处理f[i][j][k]表示前i位数,最高位是j,k出现的次数. f[i][j][k] = \(\sum_{t=0}^9\) f[i-1][t][k]; (j!=k) f[i][j][k] = 10i-1+\(\sum_{t=0}^9\) f[i-1][t][k] 阅读全文
posted @ 2021-05-31 02:06 acmloser 阅读(36) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 莫得思路,参考大佬的题解(.) 思路: 1. 整除所有数位的数 == 整除所有数位的lcm 2. sum%(a*b)%b = sum%b; dp方程: f[pos][pre_sum][pre_lcm]+=f[pos-1][pre_sum*10+i][lcm(pre_lcm, 阅读全文
posted @ 2021-05-30 23:43 acmloser 阅读(29) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 这道题能用递推的方式实现吗...如果有请告知本蒟蒻(.) 错误思路: 建立dp数组f[pos][len][last]表示枚举到第pos位,目前长度为len,上一位是last的情况.如果我们枚举的i>last,len+1.如果i<=last,len不变,last不变. WA数 阅读全文
posted @ 2021-05-30 15:17 acmloser 阅读(42) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp+状压dp 思路: 因为要求每个数字的出现次数,我们只能把所有数字的出现次数记下来.因为数字比较少考虑状压.有三种状态: 0:没出现过 1:出现奇数次 2:出现偶数次 这道题的状压dp预处理并根据情况计数感觉不是很好实现,如果用记忆化搜索我们只需要到终点看是否合法就行.注意前 阅读全文
posted @ 2021-05-30 11:07 acmloser 阅读(31) 评论(0) 推荐(0) 编辑
摘要:一.递推 学的第一种方法就是这个,但是个人认为这种方式在某些题上比较难实现,比如:Blance Number(HDU-3709).这道题本蒟蒻没想出怎么用递推预处理,反而是记忆化搜索的方式更容易懂. 以HDU-2089为例,本题的递推还是比较好实现的. 代码 二.记忆化搜索 这种方法就比较烂大街了, 阅读全文
posted @ 2021-05-30 10:59 acmloser 阅读(73) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 思路: 预处理的思路就是像背包dp那样不超过体积V的方案数,这里V对应f(a). #include <iostream> #include <cstring> #include <vector> using namespace std; typedef long long 阅读全文
posted @ 2021-05-29 22:53 acmloser 阅读(52) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 这个用循环没想出来怎么写,反倒是dfs写法很容易理解(.),菜是原罪,如果有循环预处理写法请告诉本蒟蒻QAQ. 思路: 参考数位dp记搜模板.dfs带四个变量: LL dfs(int pos,int sum,int mid,bool limit) /*分别是枚举到第几位,平 阅读全文
posted @ 2021-05-29 20:57 acmloser 阅读(32) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 思路: 入门题(然后做了一个小时) 这里预处理方案数是用组合数.如果我们直接套模板会发现答案不对,因为我们不同数字的二进制位数不同,前导零不应该被计入. 先算出n有的二进制位数符合条件个数,然后再计算二进制位数比n小的即可. ##Code #include <iostrea 阅读全文
posted @ 2021-05-29 15:23 acmloser 阅读(31) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 思路: 只从看了那道CF55D题我数位dp越写越懵(.) 这道题用容斥原理写的,有正常的循环写法: GO 要注意求的数不同,最后判断条件也不同. Code #include <iostream> #include <cstring> #include <vector> us 阅读全文
posted @ 2021-05-29 13:58 acmloser 阅读(32) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 思路: 应该是入门题,但我WA了两次....这道题直接求连续的49反而不大好求,我们反过来求不连续49的个数,然后再减去即可. ##Code #include <iostream> #include <cstring> #include <vector> using nam 阅读全文
posted @ 2021-05-29 11:47 acmloser 阅读(32) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:贪心+思维 思路: 将所有数字化为k*p+b,每次优先队列更新最大值,都会将最大值的k压为次大值的k.我们从大到小遍历,求解k次操作后,最大值的k,已经确定最大值所在位置idx. 求完之后,k可能有多.需要将idxn 之间的数再均摊k.但是注意它们只能均摊idxn长度的k.剩下的k, 阅读全文
posted @ 2021-05-29 09:15 acmloser 阅读(43) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:贪心 这题不难,但是本蒟蒻是fw.主要是没分析出点的性质,发现了点的个数很少后没啥反应(.) 思路: 注意到点的坐标是倍增增长的,根据起始坐标的范围,最大能运动到(2*1016,2*1016)处.a最小是2,因此最多是60个点. 接下来就没想到了,因为点坐标是倍增增大的,因此1~i的 阅读全文
posted @ 2021-05-29 03:05 acmloser 阅读(33) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:数位dp 思路: 预处理时,不计入每位数字为4或首位为6,次位为2的数字. 但是注意计算左分支的时候,我们是ans+=f[i+1][枚举的数字],如果枚举的数字为2,实际还需特判上一位.因为预处理首位数字为2时没有考虑上一位是什么. Code #include <iostream> 阅读全文
posted @ 2021-05-28 09:50 acmloser 阅读(34) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路有点跳跃,反正我是没想到() 思路: 我们发现操作1:石子数-1. 操作2:堆数-1.每次操作都变化的堆数+石子数的和的奇偶性.而堆数+石子数-1 = 能操作的最大次数. 再发现当堆数 = 1,石子数 = 1是必经局面,先手必胜.堆数+石子数-1为奇.如果某个局面先手必胜 阅读全文
posted @ 2021-05-27 12:10 acmloser 阅读(49) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:构造+贪心 思路: 最小值很容易想,如果叶子结点之间的距离都为偶数,那么minv = 1.如果存在一个奇数那么minv = 3. 最大值本蒟蒻没想到,实际上只要两个叶子结点之间距离==2,那么这两个叶子结点之间必同权值.如果dist>2,那么一方可选择的值就很多,必然不会相同.这个不 阅读全文
posted @ 2021-05-27 02:47 acmloser 阅读(29) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路: 这道题像上题一样解释阶梯博弈会发现行不通,因为0位置可以被多个点占据,而上题所有位置都是一个棋子. 那么怎么解呢?博弈论的快速解法就是去找必败态.我们可以发现: 先手只能移动一组里左边的石子,如果k在组里的第二个,那么先手必败. 如果k在组里的第一个呢? 接下来讨论n 阅读全文
posted @ 2021-05-26 21:02 acmloser 阅读(39) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路: 看了大佬题解才发现是阶梯博弈,这里讲一下为什么是阶梯博弈. 以第二个样例: 1 5 6 7 9 12 14 17 我们计算出每个人可以移动的距离数组b:0 3 0 0 1 2 1 2 假设我们把第二个人往左移动2格,该数列变成:0 1 2 0 1 2 1 2 有没有发 阅读全文
posted @ 2021-05-26 11:26 acmloser 阅读(20) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路: 威佐夫博弈,求先手必胜的第一步. 要先手必胜,即把后手面临的局面改为先手必败.当n==(m-n)*k即先手必败.这里分两种情况: (m-n)*kd,d<n时,我们可以从n堆里取,但我们需要保证新局面下m,与n的差值不变,才能保证差值*kn 从m堆里取,此时m堆的值不可 阅读全文
posted @ 2021-05-26 01:16 acmloser 阅读(66) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 参考大佬的对称博弈,本蒟蒻是没推出来. 思路: 先来看没有成环的情况. n为奇,先手去掉中间的石子,随后后手不管选什么都破坏平衡,先手对称选哪些,因此平衡局面0 0必然被先手遇到. n为偶,先手去掉中间两个石子,随后又形成了平衡局面.由上面先手又必胜.但是如果k==1,则先手 阅读全文
posted @ 2021-05-25 22:11 acmloser 阅读(35) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:贪心+栈 本蒟蒻的思路: 检查"NO":计算每次-操作的价格最大值与最小值,如果不在此范围输出NO. 当时想出的赋值方式是while存储所有可能取值,这时间复杂度最坏O(n2).而且这种思路也比较麻烦,计算最大值与最小值也需要while处理. 参考大佬的思路: 检查NO不是通过范围取 阅读全文
posted @ 2021-05-25 15:05 acmloser 阅读(55) 评论(0) 推荐(0) 编辑
摘要:原题链接 题意:求构造c[k] = b[i]-a[j],求(最大差值-最小差值)的最小值 考察:双指针 错误思路: 排序b,a.输出b[n]-a[n]-b[1]+a[1].实际上最大差值不一定由b[n]构成,最小差值不一定由b[1]构成.如果b数组都相同,最大差值和最小差值可以是同一个数. 正确思路 阅读全文
posted @ 2021-05-25 12:18 acmloser 阅读(41) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:构造 思路: 这题的构造应该很简单吧....两两构造即可.本蒟蒻想到了正确思路但被我否了!!!我是彩笔WA两次!!!! Code #include <iostream> #include <cstring> #include <algorithm> using namespace s 阅读全文
posted @ 2021-05-25 11:04 acmloser 阅读(38) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路: 这题不会只能说明对sg函数理解不够透彻了(比如我. 明确sg函数是解决所有ICG游戏的通解,而本题很明显是ICG游戏(所有执行步骤与执行者无关). 那么所有面朝上的硬币都可以视为一个起点.以下标为0的面朝上硬币为例,那么sg(0) = 1.由此也可以推到sg(1) = 阅读全文
posted @ 2021-05-24 21:43 acmloser 阅读(38) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路: 发现这种n比较大的,比较难找胜态和败态.像上题一样考虑sg函数打表,但是本题的石子移动是可以移动到其他堆的,本蒟蒻是不会写本题的sg函数(). 这样只能研究A,B的移动方式了,实际有点类似阶梯博弈,可以发现(A+B)%6==3时可以移动A >B.此时枚举0~5之间的数 阅读全文
posted @ 2021-05-24 18:07 acmloser 阅读(84) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 看了其他题解都是不难发现...,果然是我太弱了(.) 思路: 这题不是打表胜负态,而是打表sg函数.可以发现4个一循环. Code #include <iostream> using namespace std; int n; int main() { int T; scan 阅读全文
posted @ 2021-05-24 13:05 acmloser 阅读(35) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路: sg函数打表找规律,发现n%(p+q)后,若1<=n<=p则必败. 想说一下的就是,sg函数的必败点不能定义为>0的数.这样会让某些必胜点sg(x)>0被判断必败. Code #include <iostream> #include <cstring> #includ 阅读全文
posted @ 2021-05-24 11:11 acmloser 阅读(29) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:博弈论 思路: 每次可以选择两个方向,往正方向走,如果0在偶数个位置必胜.往反方向走,如果0在离n+1的距离有偶数个距离也必胜. ##Code #include <iostream> #include <algorithm> using namespace std; const in 阅读全文
posted @ 2021-05-23 15:33 acmloser 阅读(30) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:构造 思路: 异或和为u,数值和为v.如何判断不可能成立? u>v 即不成立.很明显因为u是v的不进位加法. u&1 != v&1 .正如上面说u是v的不进位加法.进位是不会改变奇偶性的.理性证明就是 v = u + 2*(u&v) u&v得到u哪些位置该进位,把它们左移一位即可. 阅读全文
posted @ 2021-05-23 11:26 acmloser 阅读(27) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:构造 思路: 求所有构造图内任意两点Mex(u,v)最大值最小的构造图. 考虑如何求Mex(u,v)的最大值.在同张图上,路径更长的边比路径更短的边Mex值要大.所以我们考虑树上的"链". 如果只有一条链,任意构造即可. 如果有>1条链子,由贪心思想,我们不要让0,1,2..在一条边 阅读全文
posted @ 2021-05-23 10:03 acmloser 阅读(34) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:思维 思路: 我是菜狗,连A题都不会.这道题实际就是1和n-1. ##Code #include <iostream> using namespace std; int n; int main() { int T; scanf("%d",&T); while(T--) { scanf 阅读全文
posted @ 2021-05-23 09:44 acmloser 阅读(39) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 思路: 如果做过校门外的树(增强版)那道题,应该可以想到是建立两个线段树.一个维护基友和女神约会时间tr[0],一个维护女神时间tr[1]. 对于基友相约t,我们求出tr[0]的t个空白时间的最左端点,然后更新tr[0];对于女神相约t,先求出tr[0]的左端点,没有就求tr 阅读全文
posted @ 2021-05-23 00:24 acmloser 阅读(45) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 思路: 和校门外的树(增强版)那道题差不多,我们不用管哪些瓶子有花,哪些没有.只要add,范围内从小到大 = 1.只要删除,sum[l,r] = 0. #Code #include <iostream> #include <cstring> using namespace s 阅读全文
posted @ 2021-05-22 19:22 acmloser 阅读(28) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 思路: 维护序列的扩展版. 1操作 : 区间修改 2操作 : 区间修改 3操作 : 类似线段树染色的区间修改. 4操作 : 区间查询. 对于操作1,2,3考虑每个操作如何影响需要维护的平方和,立方和. 原平方和: a2+b2+c2+... 操作1后: (a+x)2+(b+x) 阅读全文
posted @ 2021-05-22 15:40 acmloser 阅读(39) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 思路: 线段树染色+dfs序. 关于dfs序的讲解GO! ##Code #include <iostream> #include <cstring> using namespace std; const int N = 50010; int n,sz[N],h[N],idx, 阅读全文
posted @ 2021-05-22 02:57 acmloser 阅读(32) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 完全没思路,乍一眼看还以为是并查集. 大佬的思路: D操作:单点修改 R操作: 单点修改 Q操作: 区间查询 我:??? 思路: 这道题求最大的连通数的思想有点类似这题Imbalanced Array CodeForces - 817D 因为村庄都是一维的,所以最大连通数一定 阅读全文
posted @ 2021-05-22 00:06 acmloser 阅读(38) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树(扫描线) 三维扫描线求重合>=3次的体积. 完全没想出来三维怎么推,结果发现是切片(.) 思路: 从小到大枚举z.求平面在枚举z范围内的重合>=3次的面积.ans累加即可. 这里求重合>=3次的不能用之前的懒标记法了.每个点遍历1000*2*N遍会TLE.因此采用更好的优化思 阅读全文
posted @ 2021-05-21 23:41 acmloser 阅读(27) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 扫描线求周长 思路: 以x轴为例,先看图. 由此就比较好求了.这里cnt有值就可以贡献长度,所以可以不用push_down. Code #include <iostream> #include <cstring> #include <algorithm> #include < 阅读全文
posted @ 2021-05-21 01:30 acmloser 阅读(50) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树(扫描线) 通过本题终于稍微弄懂点扫描线了. 思路: 之前的HDU 1542 Atlantis.因为只要在修改前出现过一次就会被计入长度.且区间总是成对出现,也就是不用处理新的区间. 本题只有出现次数>1才会被记录有效长度,此时在修改前需要处理新出现的cnt>1的区间.即需要将 阅读全文
posted @ 2021-05-20 22:36 acmloser 阅读(37) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树+剪枝 思路: 参考大佬的思路.线段树也能剪枝是我没想到的. 最大的数263最多开方6次就会变成1.考虑到这点可以考虑暴力.每次修改[l,r]实际转化为单点修改,但是要进行剪枝,如果当前区间的最大值已经 = 1,那么就没必要在往下搜. 时间复杂度最坏是O(6*4*N+1e5*l 阅读全文
posted @ 2021-05-20 16:06 acmloser 阅读(48) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 思路: 还是线段树染色问题.. 但还是和上一题有点区别,单以样例1来说: 5 0 4 4 > 1 5 5 0 3 1 > 1 4 2 3 4 2 > 4 5 3 0 2 2 > 1 3 3 0 2 3 > 1 3 4 颜色与我们定义线段树区间颜色表示相冲突,所以进行坐标偏移. 阅读全文
posted @ 2021-05-20 13:21 acmloser 阅读(40) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 线段树染色问题 思路: 每次张贴海报都是一次区间修改.而染色区间l,r范围过大.需要离散化.离散化后就可以定义线段树了. struct Node{ int l,r,c;//l,r左右端点.c为该区间的颜色,同时也是懒标记 }tr[N<<3]; 这里定义c为该区间颜色种类是不可 阅读全文
posted @ 2021-05-20 09:08 acmloser 阅读(32) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 or 模拟 模拟是很简单啦,主要考虑线段树怎么写,本题的线段树比较特殊. 思路: 基本是参考了大佬的题解.本题的懒标记过于特殊把我写懵了.... 操作 0:砍掉[l,r]区间的树与树苗 操作 1:种植[l,r]区间的树苗. 抽象到线段树操作就是 0: [l,r]区间 树数组- 阅读全文
posted @ 2021-05-20 00:36 acmloser 阅读(249) 评论(0) 推荐(1) 编辑
摘要:原题链接 考察:线段树 思路: 很明显是设置两个懒标记,tag_1标记修改的累加和,tag_2标记修改的累乘积.但是直接这么写会WA,原因是具有运算优先级.假设修改区间为s,s*c1+c2 与 s*c2+c1是完全不同的结果. 需要统一运算优先级.也就是规定先乘还是后乘.如果我们后乘,即(s+c)* 阅读全文
posted @ 2021-05-19 20:52 acmloser 阅读(103) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树(扫描线) 思路: 其实是扫描线入门题.(然后就看了很久才略懂) 本题思路还是直接看大佬博客吧GO 想解释的只有几个问题. 为什么结构体如此定义? struct Node{ int l,r,cnt;//实际代表含义是[l,r+1]区间 double len;//cnt是指该区间 阅读全文
posted @ 2021-05-19 02:50 acmloser 阅读(34) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 思路: 第一个操作:表示把 A[l],A[l+1],…,A[r] 都加上 d.显而易见的差分优化为单点修改. 第二个操作:求[L,R]区间的gcd. 通过这两个操作思考怎么定义结构体.模板L,R然后很明显需要一个变量val记录[L,R]区间内的gcd.但是如果我们把线段树维护 阅读全文
posted @ 2021-05-18 02:07 acmloser 阅读(60) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:线段树 思路: 参考线段树模板.对于线段树结点我们需要定义使得能求出连续区间的子段和. [l,r]这是模板 maxn 表示[l,r]区间内最大的连续子段和. 但是这样我们能从子节点的子段和推到父节点吗?答案是不能的.考虑父节点的子段和要如何求.父节点的maxn有三个来源: (1) 左 阅读全文
posted @ 2021-05-17 20:58 acmloser 阅读(55) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组 思路: 类似于树状数组的扩展,利用差分数组将区间修改转为单点修改,单点查询改为区间查询.最后输出单点值%2即可. #include <iostream> #include <cstring> using namespace std; const int N = 100010 阅读全文
posted @ 2021-05-16 16:00 acmloser 阅读(31) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组 思路: 操作1:读入 l,r 表示在 l 到 r 之间种上一种树,每次操作种的树的种类都不同. 有点像差分,在[l,r]区间内加入同一种树.但是不能全部加1,最后答案是计数种类数.比较直观的想法就是在x = l处+1,x = r处-1.但是当询问[1,r+1]等区间时应该输 阅读全文
posted @ 2021-05-16 15:01 acmloser 阅读(59) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组 思路: 操作1: 将序列的第k个数改为a 很明显的树状数组单点修改 操作2:在这个序列上,每次选出c个正数,看是否能-s次 这个操作与区间大小无关,也就是所有操作都是在整个序列上进行的.我们需要求出正数的个数,并且求出是否每次能选出c个-1. 每个操作都是a>=0,所以直接 阅读全文
posted @ 2021-05-16 11:55 acmloser 阅读(62) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组 思路: 本蒟蒻是完全想不到怎么写....参考大佬题解. 求种类数,可以处理的方法一个是针对询问实时加入数.但是这样一定会TLE,然后不好求重复的数字数. 参考大佬的题解,正解做法是i从1~n实时加入数,到询问的右端点求ans.这里与求逆序对的方法不同的是tr[i]表示下标为 阅读全文
posted @ 2021-05-15 23:36 acmloser 阅读(55) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组+离散化 思路: 很明显先离散化能力值.然后建边开始dfs树. 比较难想的是如何求每个点比它能力高的子结点数量~~(对本蒟蒻而言)~~ 首先确定搜索顺序.先遍历子结点,然后再单点加入自己的权值.深度深的子节点可能会被深度浅的父节点用到更新,因此不能删除树状数组在子节点的存储的 阅读全文
posted @ 2021-05-15 20:32 acmloser 阅读(49) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组+hash 本题的总结: 如果b可以交换任意元素到a,那么最少交换次数 = 环长度-1 如果b需要交换相邻的到a,那么最少交换次数 = 逆序对数目. 思路: 这道题如果贪心把每个数列的数字尽可能换成一样的是错误的.例二就是HACK数据.既然这样我们就考虑怎么转化答案式子来求最 阅读全文
posted @ 2021-05-15 17:31 acmloser 阅读(65) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组+二分 完全没想到,fw本f 思路: 这道题实际有点像逆康拓展开.对于某个位置i,在它前面的数有a[i]个.第一头牛是无法确定身高的,但是如果我们从后往前考虑就可以用排除法确定身高. 对于最后一头牛,比它矮的有a[n]个,说明它是1~n中,第a[i]+1个数.我们考虑第n-1 阅读全文
posted @ 2021-05-15 12:04 acmloser 阅读(45) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组+差分 上一道题的加强版,但还是结合差分数组 思路: 操作一:"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。 这里还是得用到差分,设b数组为原数组的差分数组,那么此操作就转化为单点修改 操作二:"Q a b" 询问[a, 阅读全文
posted @ 2021-05-15 10:01 acmloser 阅读(28) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树状数组 确实简单....就是差分+树状数组即可.本蒟蒻还以为又有什么神乎其神的优化..... 思路: 我们先看第一个指令:第一类指令形如 C l r d,表示把数列中第 l∼r 个数都加 d。 l~r区间内+d .单看这个操作容易想到差分. 即 修改b[l]与b[r+1] 再看第二 阅读全文
posted @ 2021-05-15 01:02 acmloser 阅读(42) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:并查集 并查集维护序列的连通性 Y总在课上提过的题目,本蒟蒻果然不会 思路: 本质是快速染色某个区间.并查集可以帮助我们快速找到第一个未染色的点. 设p[i]为以i为起点第一个需要还未涂色的点(包括i) .通过findf(i)可以帮助我们找到第一个未染色的点.我们在for循环染色[l 阅读全文
posted @ 2021-05-13 21:45 acmloser 阅读(49) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:枚举 思路: 枚举四个边角的情况就行..... 疯狂WA到我麻木....看了题解发现是和A一样的解法.... 1 #include <iostream> 2 using namespace std; 3 int n,op[4]; 4 bool check(int s) 5 { 6 i 阅读全文
posted @ 2021-05-13 20:27 acmloser 阅读(44) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:并查集+离线 和这题有点像的题 HDU 3938 (本蒟蒻甚至写过) 思路: 乍一看似乎是LCA,但是询问两点最短距离必定TLE.我们可以发现两点之间的最短边首先是原题给定一条边,然后再对该边进行延伸.假定当前给定值是k,我们枚举边,将边两端进行合并,这样就是符合条件的结点个数.当k 阅读全文
posted @ 2021-05-13 16:56 acmloser 阅读(76) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:LCA+二分答案 这题也太难想了,本蒟蒻完全不会QAQ 思路: 树上建边,然后每个任务都是一个查询,我们可以利用LCA求出树上任意两点的时间和.这道题要求去除一条边后最小的最大值. 两个最字很容易想到二分答案.假设二分答案为mid.对于每一个任务,检测它的时间是否会>mid.如果会统 阅读全文
posted @ 2021-05-12 13:49 acmloser 阅读(72) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树上差分 思路: 点差分.区别在于中间点多+了1.注意不能在dfs前对差分数组-1.这样会导致递推错误.比如下图: 1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 using namespace std; 阅读全文
posted @ 2021-05-12 09:39 acmloser 阅读(54) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树上差分 思路: 点差分模板题.定义d[i] 为某路径上经过i的次数. 1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 using namespace std; 5 const int N = 50010 阅读全文
posted @ 2021-05-12 01:13 acmloser 阅读(58) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:LCA+最大生成树 思路: 实际是求两点之间最大的最短边.这样很容易想到二分,但是直接二分会TLE. 然后又会想到次小生成树,但是这道题边不能构成树.由于我们要的边尽量大,可以考虑贪心一波建立最大生成树.然后求两点之间的最小距离直接套LCA倍增板子.这题比次小生成树省事. 时间复杂度 阅读全文
posted @ 2021-05-11 23:45 acmloser 阅读(101) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:LCA 思路: md想到了两两求lca但是没敢继续想下去...我是sb 最近公共祖先一定是对u,v来说最近的,但是对于第三个点需要两两枚举求最小值. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 阅读全文
posted @ 2021-05-11 21:02 acmloser 阅读(51) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:思维 顺着LCA的标签而来,结果这题貌似没什么关系(甚至想半天没想出来( 思路: 我们发现每个子结点和父节点都差一个斐波那契数.对于样例的树可以表示成 (1) (2) (3) (4 5) (6 7 8) (9 10 11 12 13) 每个数字减去斐波那契数列中最大但严格小于自己的数 阅读全文
posted @ 2021-05-11 15:13 acmloser 阅读(42) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:LCA + 枚举 完全不会...LCA真难.... 思路: 很容易看出两个分为两段的方式: 附加边加上成环后,环上去掉一个树边和一个非树边. 未成环的树边去掉一个边,然后任意去掉一个非树边. 设d[x] 表示 x点到其父节点的边上要去掉d[x]条非树边才断. 考虑枚举非树边,对于非树 阅读全文
posted @ 2021-05-11 14:03 acmloser 阅读(44) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:LCA+Tarjan 思路: 因为N<=1e5,所以上个算法N2 不适用.这里仍然是上道题的思路,枚举所有不在最小生成树的边.求出边两端点u,v.找到u,v在最小生成树的最大值d1和次大值d2.然后通过sum-d1(d2)+road[i].w求解答案. LCA优化的是求两端点之间的最 阅读全文
posted @ 2021-05-10 21:56 acmloser 阅读(45) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:贪心+思维 原来是贪心...还以为是dp 思路: m个已知信息将n个元素序列分成了n+1段.对于每段端点求峰值即可. 但是注意第一天的起点是任意高的. 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 阅读全文
posted @ 2021-05-10 01:30 acmloser 阅读(74) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察: 思维+构造 错误思路: 以451为例.这道题不是从大到小枚举,再取余,存在取小的数更优的情况.dfs一定超时,完全背包不便记录路径. 思路: 我们的集合只包含0与1的数.如果要表示451的4一定需要4个100,5需要5个10.以此类推,由此n每位数字的最大值就是答案的最小长度. 然 阅读全文
posted @ 2021-05-09 23:45 acmloser 阅读(53) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:差分约束+二分 这题太呕了,调bug调了几个小时. 错误思路: 贪心,根据已经确定成绩的A,B求解最大值T. 可能存在这样的情况:a要k+T倍杀b,c要被b k-T倍杀,已知a、c的分数。那么有可能b无论取什么分数,这两个flag至少会不满足一个,也就是说可能会这样:b取大了a不能k 阅读全文
posted @ 2021-05-09 12:59 acmloser 阅读(72) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:差分约束 艹,我太菜了,想了半天不知道源点在哪里,结果是每个点都试一遍... 思路: 看了其他大佬的博客,实际我是没有理解差分约束的,这里不需要求最值解,只需要求可行解,而无需管它们的实际意义, 假设所有解都<=0,那么根据条件求出所有解,而所有解+d是满足解<=d的可行解.所以直接 阅读全文
posted @ 2021-05-09 01:45 acmloser 阅读(75) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:差分约束+二分+前缀和 思路: 某个区间有多少个,考虑前缀和. 那么: s[i] - s[i-1] >= 0 , s[i] - s[i-1] 表示第i小时雇佣的人,s[i] - s[i-1] <= sum[i] sum[i]表示可以在i时刻开始工作的人数. 注意r[i]表示第i小时需 阅读全文
posted @ 2021-05-08 23:59 acmloser 阅读(44) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:差分约束 错误思路: 设di 为 第i头牛的坐标, 由题可以得到 dB - dA <= L . dB - dA >= D . 两边减少d1 ,设f[i] = di - d1 , 答案是求f[n]的最大值. 这样确实可以建边,但是找不到源点.1不能保证到所有的点.如果用 di-1 <= 阅读全文
posted @ 2021-05-08 12:36 acmloser 阅读(39) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:差分约束 对本蒟蒻来说想到怎么建立差分约束系统就即为不容易. 思路: 根据题目,求满足 ai <= x <= bi 至少有Ci个 的最小集合.在某个区间里至少有Ci 个,我们可以联想一波前缀和. 这个式子转化为前缀和为 sum[b] - sum[a-1] >= Ci n个条件就有n个 阅读全文
posted @ 2021-05-08 11:24 acmloser 阅读(40) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:差分约束+SPFA 引入: 什么是差分约束? 差分约束系统是一个n元一次不等式组. 它的作用包括: (1) 求一组不等式的可行解 (2) 求一组不等式的最大值或最小值.(每个变量的最值) 不等式的格式是 : Xi \(\leq\) X j + C (C为常数) 这里联想到最短路问题, 阅读全文
posted @ 2021-05-08 00:01 acmloser 阅读(57) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:01分数规划+SPFA判环 思路: 和之前的最小环没什么区别,本题最难在建边.看题目很想当然的是二重for循环字符串建边,但是明显会TLE并且MLE, 考虑换一个思路, ababc + bckjaca -> aba bc kjaca 只考虑前面两个与结尾两个,就转化为 ab-> bc 阅读全文
posted @ 2021-05-07 00:59 acmloser 阅读(56) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:树形dp+二分 思路: 化为01分数规划后,每个人的贡献是 p[i] - mid*s[i],注意一下后面并非图论问题,因为不需要回到源点.因为取某个人的条件是那个人的推荐人也在队列中,所以是树形背包问题. 普通的树形背包时间复杂度是O(n3),TLE是明显的.(所以本蒟蒻紧急学了树形 阅读全文
posted @ 2021-05-06 22:10 acmloser 阅读(56) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:01分数规划+SPFA 思路: 基本是和观光奶牛一样的题,这题的边权化为 sgma(w[i]) - mid.然后判断是否存在负环. 但是会TLE 5个点,此时可以用玄学优化,如果已经转了5圈就说明存在负环. 1 #include <iostream> 2 #include <cstr 阅读全文
posted @ 2021-05-06 18:13 acmloser 阅读(40) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:01分数规划+01背包 错误思路: 二分求最大值,check函数里对 t[i] - mid*w[i]排序,从大到小选,只要和为sum就一直选,最后检测选择的W是否>=m 这个思路错在不能从大到小选,因为存在t[i] - mid*w[i]很小,但是w[i]很大使原本从大到小的W>=m 阅读全文
posted @ 2021-05-06 16:37 acmloser 阅读(65) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:01分数规划 思路: 由奶牛观光所说,01分数规划基本是在考察二分与其他算法的结合.这里也可以化为累加 a[i] - mid*b[i] 注意原式子*100,所以mid需要/100 我们用C数组保存a[i] - mid*b[i]的值,然后选出最大的n-k个,如果和>=0就说明正确. 1 阅读全文
posted @ 2021-05-06 10:35 acmloser 阅读(46) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:二分+SPFA 引入:形如 ${\sum_1n f[i] \over \sum_1n g[j]}$求其最大值,称为01分数规划问题.通过二分最大值,检验解的存在性,这样的存在性具有单调性,所以可以用二分解决. 思路: 想到二分之后,我们可以假设最大值 = mid,对于每一个环,检验$ 阅读全文
posted @ 2021-05-06 01:12 acmloser 阅读(42) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:次小生成树 思路: yysy,切模板题很爽,但是莫得进步555 时间复杂度:O(T*(mlog2m+n2+m)) 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace s 阅读全文
posted @ 2021-05-05 15:13 acmloser 阅读(45) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:次小生成树 思路: 模板题,这里我用的方法一,时间复杂度O(N*M+Mlog2m) 1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 using namesp 阅读全文
posted @ 2021-05-05 13:25 acmloser 阅读(42) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:次小生成树 思路: 求免去费用道路两端玩具之和A/生成树权值B的最大值. 按贪心思想,应该是让B尽可能的小.对于A可以枚举每一条边,对于B是先求最小生成树的权值和. 如果免费的边在最小生成树中 ans = max(ans,A/最小生成树的权值和-road[i].w) 如果免费的边不在 阅读全文
posted @ 2021-05-05 13:00 acmloser 阅读(42) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最(次)小生成树 思路: 很明显是求解严格次小生成树. 在当前图所有能构造树的方法中,边权和是第二大的生成树. 求次小生成树的两种方法: 1.先求最小生成树,枚举删取最小生成树的一条边,然后再做最小生成树 时间复杂度O(mlog2 m+nm) 但只能求非严格次小生成树 2.先求最小生 阅读全文
posted @ 2021-05-05 09:55 acmloser 阅读(124) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最小生成树 思路: 本题要求完成图的最小生成树依旧是原树.考虑Kruskal算法,每次都是选择当前边两端合并为一个集合,我们要保证为完全图的话需要让左右端点的集合两两之间连一条边,同时保证原树的边是当前集合最小的边.因为原边不能代替所以考虑取road[i].w+1的边,边的数量是左端 阅读全文
posted @ 2021-05-04 17:07 acmloser 阅读(56) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最小生成树 思路: 一眼扫过去超像Prim算法,实际上最小生成树的两种方法皆可.当我们刚开始建矿井时就像有个虚拟源点向实点伸展了一条边,所以建立个虚拟原点即可. 这道题是无向边所以不用管u,v到底哪个是被建矿井的端点. 1 #include <iostream> 2 #include 阅读全文
posted @ 2021-05-04 10:32 acmloser 阅读(60) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:Floyd 思路: 每次0操作都是加入一个点,这个操作有点像Floyd,Floyd算法也是每次操作加入一个点,然后更新.但直接每次加入新点就Floyd会超时,所以要对Floyd算法优化. 每次加入一个新点,就直接更新与该点有关的边.但有个误区是不能只更新已加入点与新点直接的边.比如1 阅读全文
posted @ 2021-05-03 20:18 acmloser 阅读(39) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:floyd 思路: 很明显的传递闭包,但是我们直接敲板子上去会TLE.神级剪枝在floyd的第三重循环,如果g[i][k] = 0那么第三重循环没必要进行. 1 #include <iostream> 2 #include <cstring> 3 using namespace st 阅读全文
posted @ 2021-05-03 17:37 acmloser 阅读(51) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:Floyd+输出路径 错误思路: 跑一遍Floyd,记录使g[i][j]>g[i][k]+g[k][j]+w[k] 变小的k.分为[l,k] [k,r]输出路径. 当g[i][j] = g[i][k]+g[k][j]+w[k],比较path[i][j] 与当前枚举点k的大小. 错误原 阅读全文
posted @ 2021-05-03 17:07 acmloser 阅读(35) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:Floyd+矩阵快速幂 思路: 前面讲过Floyd算法的第一层循环是i~j的最短路,经过1~k的结点.在这里我们将Floyd的dp状态表示f[k,i,j]. 假设i经过a条边到达S, f[k,i,j] = f[a,i,S]+f[k-a,S,j] 我们可以发现前a条边的路径与后面的路径 阅读全文
posted @ 2021-05-03 09:12 acmloser 阅读(140) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:Floyd 思路: 考察Floyd算法应用之最小环.在应用Floyd之前我们先了解Floyd的本质. 1 for(int k=1;k<=n;k++)//起点到终点之间经过1~k点 2 for(int i=1;i<=n;i++)//枚举起点 3 for(int j=1;j<=n;j++ 阅读全文
posted @ 2021-05-02 22:52 acmloser 阅读(52) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:Floyd 思路: 传递闭包应用题.也可以用拓扑排序,这里先练下传递闭包.拓扑排序以后补 传递闭包模板: 1 for(int k=1;k<=n;k++) 2 for(int i=1;i<=n;i++) 3 for(int j=1;j<=n;j++) 4 if(g[i][k]&&g[k 阅读全文
posted @ 2021-05-02 11:25 acmloser 阅读(48) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最短路 思路: 较水,正反向建图求和. 1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 using namespace std; 5 typedef long long LL; 6 typedef pai 阅读全文
posted @ 2021-05-01 23:40 acmloser 阅读(41) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最短路+思维 完全不会,废物本废 错误思路: 比较明显的思路就是以每个特殊点为起点,然后Dijkstra,再以每个特殊点为终点求最小值,显而易见地TLE 解法一(官方题解): 由暴力思路延伸来的思路.因为我们只需要知道最小值,而不是特殊点.所以起点和终点是谁无所谓.所以可以将上述的一 阅读全文
posted @ 2021-05-01 22:41 acmloser 阅读(74) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最短路 思路: 拆点.只有一个状态不足以求出最小花费,需要再加上当前点用了几次免费机会. 坑点: 存在起点与终点经过路线<k的情况,这时候用不到k次机会,所以直接返回0的贪心是错的.... 1 #include <iostream> 2 #include <cstring> 3 #i 阅读全文
posted @ 2021-05-01 16:48 acmloser 阅读(57) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最短路 思路: 很容易看出t就是一般最短路的权值,快速地打了一遍dijkstra板子结果发现输出结果和样例不一样,那么答案错在哪里呢? 我们调试一下就可以发现,到达中间某点的耗时晚,不一定到达终点就晚,因为到达时间由到达每个点的时间和速度决定. 之前说过最短路可以和dp联系起来,那么 阅读全文
posted @ 2021-05-01 13:32 acmloser 阅读(110) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最短路+二分 思路: 二分最多的一次收取的费用的最小值,对于每一个二分值跑一遍最短路,最后判断n点是否可达即可.这里的check函数的思路类似二分经典题:搬石头 long long数组的极大值可以初始化为memset(数组,63,size) 1 #include <iostream> 阅读全文
posted @ 2021-05-01 11:40 acmloser 阅读(41) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:最短路 思路: 是模板题.Johnson算法主要用于处理负权边,它可以让Dijkstra算法计算带负权的最短路问题. 具体的做法是:建立虚点0,再让0与每个点连一条边,求出0到每个点的最短路,将(u,v)之间的权值w = w+dist[u]-dist[v]. 这样w一定为正,因为最短 阅读全文
posted @ 2021-05-01 10:33 acmloser 阅读(55) 评论(0) 推荐(0) 编辑
摘要:原题链接 考察:floyd+枚举 相差了...想的是直径端点作为加的路左右端点之一...但实际是全部枚举. 思路: 暴力枚举所有没有连通的点,然后对于加的那条路,求左端点的最远距离+右端点的最远距离+加的路线的距离 最后再与剩下的直径求最小值. 1 #include <iostream> 2 #in 阅读全文
posted @ 2021-05-01 01:41 acmloser 阅读(55) 评论(0) 推荐(0) 编辑