07 2021 档案
摘要:原题链接 考察:数论(?) 思路: 一开始还以为是背包什么的,结果数字有规律....$1689$的排列可以组成0~6的余数.剩下的数字我们随意拼即可.$0$直接全部放末尾.不存在没有数字的情况. ##Code #include <iostream> #include <cstring> #inclu
阅读全文
摘要:原题链接 考察:枚举 思路: 看懂题目省事一半,所有单元格都是需要净化的,所以最少操作数是$n$,枚举每一行,每一列,看是否覆盖所有单元格. ##Code #include <iostream> #include <cstring> using namespace std; const int N
阅读全文
摘要:原题链接 考察:思维+数论 思路: 如果存在,则所有选中点间距相等边的长度*边的条数 = \(n\).也就是边的长度是$n$的倍数.时间复杂度是$O(\sqrt(n)*n )$ ##Code #include <iostream> #include <cstring> using namespace
阅读全文
摘要:原题链接 考察:bfs 思路: 可以移动的范围不超过$10^5$,所以直接bfs.... ##Code #include <iostream> #include <cstring> #include <algorithm> #include <map> #include <queue> #inclu
阅读全文
摘要:原题链接 考察:思维+计算几何 思路: 预处理所有点的度数,存在一个最小角的包含所有的点,那么必然存在最大的相邻点之间的角度没有包含所有的点. 反三角函数的返回值是弧度,详情看此篇GO ##Code #include <iostream> #include <cstring> #include <c
阅读全文
摘要:原题链接 考察:枚举+二分 思路: 枚举其他两个药品的使用量,二分最后的使用量 ##Code #include <iostream> #include <cstring> #include <cmath> #include <vector> using namespace std; typedef
阅读全文
摘要:原题链接 考察:枚举 思路: 预处理平方,分斜边和直角边,两个直角边两种情况处理. ##Code #include <iostream> #include <cstring> #include <cmath> #include <vector> using namespace std; typede
阅读全文
摘要:原题链接 考察:组合数学+思维 思路: 如果只考虑一行的和是比较容易想到的:假设该行对应的$s$为$x$,如果$a%x==0$,那么求出$sum = \frac$的个数即可.如果有多行,就统计多行的和$x$.我们直接统计和的个数即可. 特判$!a$的情况,此时只要一个因子为0,其他任意值. ##Co
阅读全文
摘要:原题链接 考察:数论 思路: 如果先手胜,说明$n$是一个质数或者$n$存在因子,该因子只有质因数.第二个条件判断只需要$n$有两个质因子,而不需要一个个枚举因数. ##Code #include <iostream> #include <vector> #include <cmath> using
阅读全文
摘要:原题链接 考察:暴力枚举 思路: 记这道题的唯一意义是: 逆时针旋转90度后x'=-y,y=x 逆时针旋转180度后x'=-x,y=-y 逆时针旋转270度后x'=y,y=-x ##Code #include <iostream> #include <cstring> #include <algor
阅读全文
摘要:原题链接 考察:枚举,思维 思路: 不论怎么取,都存在一个间隔点:左边的都是左手拿的,右边的都是右手拿的,枚举间断点,可以发现根据取的个数不同,由于贪心是尽可能间隔取,然后再计算连续的附加值. ##Code #include <iostream> #include <cstring> using n
阅读全文
摘要:原题链接 考察:贪心 思路: 每$k-1$个间隔放,有多就从前往后放.有一些坑点要注意: $n%k$的位置和间隔的位置可以放置$m$个,这时需要特判$res$的初始值. 不能直接用左移运算符算加倍的结果.... ##Code #include <iostream> #include <cstring
阅读全文
摘要:原题链接 考察:组合数学 错误思路: DFS枚举 正确思路: 直接枚举长度是$106$的数是不可能的.但是注意到和很小,最多是$9*106$.假设$x$个$a$,则有$n-x$个$b$,如果当前和合法,那么就是两个数添位置的简单组合数学 ##Code #include <iostream> #inc
阅读全文
摘要:原题链接 考察:贪心(?) 思路: 不存在回文子串的条件是对于任意$i$,均有: $$s[i]!=s[i-1] , s[i] != s[i-2] $$ DFS枚举每一个修改的值. ##Code #include <iostream> #include <cstring> using namespac
阅读全文
摘要:原题链接 考察:数论 思路: 串联: \(\frac{a}{b}+1 = \frac{a+b}{b}\) 并联: \(\frac{a}{b}与1并联--> \frac{a}{a+b}\) 也就是说分子分母不论大小可以得到相同的结果 ##Code #include <iostream> #includ
阅读全文
摘要:原题链接 考察:DFS 思路: $mod[i]$维护$i$结点是否被修改,$anc[i]$记录$i$结点的父节点的父节点是谁.直接一次DFS即可同时求出两个值. ##Code #include <iostream> #include <cstring> #include <vector> using
阅读全文
摘要:原题链接 考察:双指针 思路: 将原数组排序后,枚举每一个$a[i]\(,求使\)(j,i)$全部变为$a[i]$的最长左边界$j$,当$a[i]$变小时,$j$只会往更左扩展. ##Code #include <iostream> #include <cstring> #include <algo
阅读全文
摘要:原题链接 考察:思维 思路: 设和为$sum$,每次减少$n-1$,最多进行$\frac{sum+n-2}$次.但是存在$a[i]$彼此相差悬殊的情况.此时答案为$max(a[i])$. ##Code #include <iostream> #include <cstring> using name
阅读全文
摘要:原题链接 考察:线性dp 思路: 想到了但三重循环以为会超时,实际是只有$j=1$时才有三重循环. ##Code #include <iostream> #include <cstring> using namespace std; const int N = 1010; int n,m,x,y,c
阅读全文
摘要:原题链接 思路: 结论题,排序奇偶分组,均分,没想出怎么证明 ##Code #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 100010; int n,sum
阅读全文
摘要:原题链接 考察:思维 or 搜索 错误思路: 二分模拟,精度爆炸 正确思路一: 搜索....我是fw 正确思路二: 双指针设置$l = 1,r = n$,如果$s[i]==l$,说明右边不会在有人,$s[i]==r$左边不会在有人. ##Code #include <iostream> #inclu
阅读全文
摘要:原题链接 考察:贪心 思路: 死于读不懂题,对于每个仓库,求裁判到它的距离,排序,两类仓库分开求,因为题目是这么说的 ##Code #include <iostream> #include <cstring> #include <cmath> #include <queue> using names
阅读全文
摘要:原题链接 考察:思维 思路: 类似RMQ的思想,对于每个点求往左,往右不减最远能到达处.求是否和会大于区间长度. ##Code #include <iostream> #include <cstring> using namespace std; const int N = 100010; int
阅读全文
摘要:原题链接 考察:构造 思路: 很容易想到先构造$gcd(a,b) = 1$的两个数,最后两个位置构造剩余的$k$.剩余$k$最大到$k-\frac {105}{2}+1$.构造$k,k*2$不会超过$109$,剩下的1到质数里成对构造.最多需要$2*105$个质数,需要开到$107$ ##Code
阅读全文
摘要:原题链接 考察:思维 思路: 制造$n$个$d$位互不相同的数字,$dfs$即可 ##Code #include <iostream> #include <cstring> #include <vector> using namespace std; typedef long long LL; co
阅读全文
摘要:原题链接 考察:计算几何 思路: 已知两点和半径可以确定一个圆,最优解的圆一定可以偏移直到相交于两点.至于怎么求圆心看 GO 求正反两遍,求不用讨论谁上下问题. ##Code #include <iostream> #include <cstring> #include <cmath> using
阅读全文
摘要:原题链接 错误思路: 枚举每一个人,优先队列贪心求最小的不重合区间组数. 思路: 实际上贪心不一定能贪到正解,这里类似背包需要枚举所有可能.背包体积是时间: $$f[i] = f[i-1],f[node[pos].l]+w $$ 需要按区间右端点排序. ##Code #include <iostre
阅读全文
摘要:原题链接 考察:模拟(?) 思路: 分类讨论就完事. (1) \(n=1\) (2) \(n=2\),这里一定要分$d = 0$的情况. (3) \(n>2\),这里一定要注意$cnt = 0$的情况,此时合法的情况是只有两种公差,且大公差一定是小公差的$2$倍. ##Code #include <
阅读全文
摘要:原题链接 考察:思维 看题目:woc好复杂 看大佬题解:我果然zz 思路: 如果要想的话需要分解到每一位考虑,第i位有几种可能,然后累乘.可以发现第i位的可能数就是第i位字母种数. ##Code #include <iostream> #include <cstring> using namespa
阅读全文
摘要:原题链接 考察:思维 错误思路: 预处理对角线和,枚举每一个点,发现与该点相邻的点都不冲突. 错误原因: 但凡图画大点就可以发现不止是相邻的点,也不是用相邻的点对角线路过的点. 思路: 正解是与枚举点奇偶性不同的点.....直接暴力枚举完事. ##Code #include <iostream> #
阅读全文
摘要:原题链接 考察:思维 思路: 说实话想到了取模,但是没细想下去,还以为前面的位数需要*10,但实际不用,求前缀模直接$L[i] = (L[i-1]*10+x)%a$.但是后缀模没有办法,只能求$10^i$模数. ##Code #include <iostream> #include <cstring
阅读全文
摘要:原题链接 考察:树形dp(?) 思路: 主要利用的两个性质: (1) 以树的重心为根时,所有子树的大小都不超过整棵树大小的一半. (2) 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上. 注意性质1不是子树的和,以贪心来考虑的话,我们对于根节点$u$,其最大的子
阅读全文
摘要:原题链接 考察:DFS 错误思路: 一开始想的是数位dp,然后发现数字是由两部分构成,后面取值范围不仅取决于后面的数字是否取到了$a[pos]$,也取决于前面数字是否取到最值.然后发现数位dp做不了= = 正确思路: 可以发现数字最多是7位,不考虑7位上重复最多$7^7$种方法.直接DFS枚举,再分
阅读全文
摘要:原题链接 考察:hash 思路: 二维hash模板题,先横着做一遍hash,再纵着坐一遍前缀和hash.获得$a,b$矩阵的hash值参考了前缀和公式: \(sum[i,j] - sum[i,b]*p1[j-b]-sum[a,j]*p2[i-a]+sum[a,b]*p1[j-b]*p2[i-a]\)
阅读全文
摘要:原题链接 考察:欧拉回路(?) 思路: 每个点$u$与$a = (u<<1)&((1<<n)-1),a+1$有一条有向边,也就是每个点的入度 = 出度 = 2.必然存在欧拉回路,$dfs$即可 但是看了网上的题解都没说为啥可以这样$dfs$,这里如果遇到遍历后的点回退,这个点与上一个遍历过的点一定有
阅读全文
摘要:原题链接 考察:欧拉路径 思路: 有向图存在欧拉路径:所有点入度 = 出度或除两个外入度 = 出度. 但此条件有个大前提就是边连通,判断边连通需要:并查集或者dfs ##Code #include <iostream> #include <cstring> using namespace std;
阅读全文
摘要:原题链接 考察:欧拉路径 思路: 根本不难,注意$ans$数组不要开小了..... ##Code #include <iostream> #include <cstring> using namespace std; const int N = 510; int m,g[N][N],d[N],max
阅读全文
摘要:原题链接 考察:欧拉回路 思路: 模板题.主要点在删除边,邻接表删除边需要将$road[i].ne$改变,否则时间复杂度是$O(m2)$,修改后的时间复杂度是$O(n+m)$. 关于$dfs$为什么用&,这是回溯时,直接得到的就是新的边,如果我们用$h[u]$修改,那么下次回溯时我们还是用的原来的边
阅读全文
摘要:原题链接 考察:欧拉路径 思路: 主要是看懂这句:**保证:铲雪车从起点一定可以到达任何街道。**这句话的意思是说铲雪车在某条道路上.结合题意发现每个点的入度出度相等,构成欧拉路径.由此答案就是所有路径和*2. ##Code //每条边都是双向道,所以每个点入度 = 出度,存在欧拉回路 #inclu
阅读全文
摘要:原题链接 考察:状压dp 虽然在二分图题单里...但我感觉是考察的状压dp.. 思路: \(n<=15\),枚举二进制,0是一个集合,1是一个集合.二分图存在当且仅当图内两点集合不存在边.我们求最小的边集合即可. ##Code #include <iostream> #include <cstrin
阅读全文
摘要:原题链接 考察:二分图匹配 思路: 最小路径点覆盖.每个任务的接连完成构成一条简单路径,求最少的简单路径覆盖所有的任务点. ##Code #include <iostream> #include <cstring> using namespace std; const int N = 510; ty
阅读全文
摘要:原题链接 考察:二分图匹配 思路: 实际考察最小覆盖点.将文物与它的关键点建边.除此之外我们需要将点分为两个集合.可以发现每个点与它的关键点奇偶性不同.由此将点分为$x+y$为奇和偶两个集合. 注意建边,需要$(x,y)\(为关键点与文物建边,\)(x,y)$与它的关键点建边. ##Code #in
阅读全文
摘要:原题链接 考察:二分图匹配 错误思路: 统计每种颜色的行数和列数,很明显不一定是全去除行(列). 思路: 对于$mp[i][j]$,如果我们去除了它,要么是去除第$i$行,要么是去除第$j$列.枚举每一种颜色$x$,所在坐标$i,j$,连接边,求最小点覆盖. 时间复杂度$O(50N^3)$ ##Co
阅读全文
摘要:原题链接 考察:二分图 思路: 求最大的集合,该集合内无边相连,即最大独立集.这里比较难把点分成二部分.我们可以直接不分,将每个点看成出度和入度,每条边(不相交)都等价于2个匹配.最后将匹配数$/2$即可. ##Code #include <iostream> #include <cstring>
阅读全文
摘要:原题链接 考察:二分图 思路: 求最大的点集合,集合内任意两点不可以抵达.求的答案略像最小路径重复点覆盖,每条路径上一定存在其他路径无法抵达的点.我们假设答案为$ans$,最小路径重复点覆盖条数为$cnt$. 明显选了一条路径上的点就不能再选这条路径的其他点.所以$ans>=cnt$ 假设每条路径的
阅读全文
摘要:原题链接 考察:二分图匹配 思路: 对于每个$a[i],b[i]$连接边,需要选择最少的点,覆盖所有的边. 对于二分图匹配问题,每个点只能枚举一次. 最小点覆盖问题,两个端点连接的边只能选择其中一个,然后覆盖所有的边. ##Code #include <iostream> #include <cst
阅读全文
摘要:原题链接 考察:二分匹配 思路: 长度为2的骨牌,相当于骨牌所占用两个点匹配,不重叠:没有一个点共用两条边,求能放的骨牌:最大匹配数. 二分匹配前一定要先判断二分图,再将点分成两派,只枚举其中一派. ##Code #include <iostream> #include <cstring> usin
阅读全文
摘要:原题链接 考察:单调队列 错误思路: 双指针.当i前进的时候,j没有回溯使得漏解. 思路: 对于每一个$sum[i]$,用单调队列保存与$i$长度不超过$k$的最小值. 注意下一个问题:因为我们一定要先把$sum[0] = 0$纳入,如果后面的$sum[i]<0$且呈非递增,就无法求解,所以答案的初
阅读全文
摘要:原题链接 考察:双指针+枚举 很经典的思路,但蒟蒻不会... 错误思路: 二分面积,然后发现需要枚举面积的约数,配合多组样例会TLE 思路: 枚举第$i,j$行,在$[i,j]\(之间作双指针求\)>=k$的最小面积. ##Code #include <iostream> #include <cst
阅读全文
摘要:原题链接 考察:双指针 思路: 很明显可以枚举$log_2sum(i,j)$的值,然后枚举左端点求右端点的区间,用二分TLE到我整个人都麻了,看题解是用双指针... 我自己想的是用枚举右端点,二分求左端点区间,也是TLE... ##Code #include <iostream> #include
阅读全文
摘要:原题链接 考察:双指针 应该算水题,但我WA了多发.... 思路: 不能右端点计数,要左端点计数,这样就不需要考虑左右两边计重. ##Code #include <iostream> #include <cstring> using namespace std; typedef long long
阅读全文
摘要:原题链接 考察:思维 思路: 从样例一很容易想到二进制1的个数一定要为偶数个,但是这样很容易想到反例:1 14,虽然总和也为偶数个但是不成立.这里就延伸出新的规则:1的个数最多的不超过总和的/2. 总结来说就是:$sum[r]-sum[l-1]$为偶,且$maxn_{l,r}<=\frac{2}$.
阅读全文
摘要:原题链接 考察:思维,数论 思路: 先考虑依据矩形边建立三角形. (1) k==1 明显不成立 (2) $n$是$k$的倍数,明显$(0,0),(0,\frac{2n})(m,0)$ (3) $m$是$k$的倍数,明显$(0,0),(0,n),(\frac{2m},0)$ (4) \(S = \fr
阅读全文
摘要:原题链接 考察:双指针 思路: 枚举和k,求$sum[r]-sum[l]==k$的最大r,注意特判0 ##Code #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N
阅读全文
摘要:原题链接 考察:计算几何 思路: 两种方法: 一:线性规划 (1) \(x-d<=y<=x+d\) (2) \(-x+d<=y<=-x+2n-d\) 二:叉乘判别法(只适用于凸多边形) 看这里GO &emps; 没找到证明,但注意外积相乘不是累乘,只与上一个乘就行了. ##Code(思路二) #in
阅读全文
摘要:原题链接 考察:二分+完全背包 错误思路: 说实话一眼看就觉得像背包,但是1e7的空间真的有点离谱,实际证明就是要敢想.后面想的贪心都贪不到最优解,枚举会超时. 思路: $f[i][j]$表示前$i$件物品,价值最少是j的最小花费. \(f[i][j] = min(f[i-1][j],f[i][j-
阅读全文
摘要:原题链接 考察:线性dp+二分 思路: 严格上升子序列长度,每个$a[i]-=i$,然后求非严格单调上升子序列长度. ##Code #include <iostream> #include <cstring> using namespace std; const int N = 100010; in
阅读全文
摘要:原题链接 考察:二分 思路: 很明显尽量取相邻的,一开始我还以为和$n,k$的奇偶有关,实际是没有关系的. (1) 无解:\(n<\frac{(1+k)*k}{2}\) (2) 将1~k偏移到$<=n$的最大$k$长度连续和,剩下的余数从大开始补. ##Code #include <iostream
阅读全文
摘要:原题链接 考察:二分+树状数组 只想到了暴力做法...最关键的从左往右和从右往左取min没想到. 思路: 队列模拟成n个空位,因为只需要考虑比当前高的,且按字典序,我们将身高排序,对于$h_i$,有&k_i&个比他高的 (1)如果在前面,那么他的位置是第$k_i+1$个空位 (2)如果在后面,位置在
阅读全文
摘要:原题链接 考察:二分 思路: 不要用圆锥比例求$r_水$,当情况是圆柱会$/0$,利用圆台上下半径差的三角形求$r_水$.二分水的高度. 其实不是很懂为什么可以二分,主要是$V_水$受$r_水$和$h_水$两个变量的影响,如果一方增大另一方就会缩小,有大佬懂t我一下. 全网貌似只有我推的算$r_水$
阅读全文
摘要:原题链接 考察:二分 思路: 前缀和,二分右端点找出现总次数为奇数的r ##Code #include <iostream> #include <cstring> using namespace std; typedef long long LL; const int N = 20010; int
阅读全文
摘要:原题链接 考察:RMQ 思路: 二维模板题 ##Code #include <iostream> #include <cstring> #include <cmath> using namespace std; const int N = 310,M = 10; int m, n,w[N][N],Q
阅读全文
摘要:原题链接 考察:枚举+RMQ 错误思路: 二分+RMQ,这里不能二分的原因是不能整除的时候,后面超出的是舍弃,舍弃部分可能会使二分答案没有单调性. 正确思路: 枚举答案,但需要优化,假设每段都可以取到最大值,那么$>k$最少需要$\frac {k+maxn-1}$.然后判断是否可行 ##Code #
阅读全文
摘要:原题链接 考察:排序,前缀和思想 错误思路: 建立d,p的树状数组,对于每一个查询是否有 <\(d[i]\)&&<$p[i]$的 错误原因: 显然p,d是一体的不能分开. 正确思路: 结构体排序按p,d优先顺序排序,对于每一个$p[i]\(,查询\)<p[i]$的最小$d[i]\(,如果\)>=d[
阅读全文
摘要:原题链接 考察:主席树+树状数组 实际是动态主席树的模板题,反正本蒟蒻不会(. 思路: 主席树实际是有n个根结点的线段树,如果我们修改第i棵主席树的值,后面i~n棵树都需要修改,时间复杂度最坏是$O(n*m)$级别的,但是主席树求区间第k小,实际就是求前缀和,而操作又涉及单点修改,这里可以考虑树状数
阅读全文
摘要:原题链接 考察:博弈论 完全给我WA麻了,没有特判4这个点,结果是一直WA. 思路: 3种情况: n为奇数,只有一种取法 n为偶数且n/2也为偶数,此时和奇数一样取 n为偶数且n/2为奇数,直接取一半. 当n==4这个点一定要特判 ##Code #include <iostream> #includ
阅读全文
摘要:原题链接 考察:主席树 写错了LCA的板子,debug几个小时... 思路: 和在一维数组上建立主席树不同,树上建主席树是以父节点为上一个版本,这里求(u,v)的第k小值,实际就是: \(tr[u].cnt+tr[v].cnt-tr[lca].cnt-tr[fa[lca]].cnt\) 写得比较繁琐
阅读全文
摘要:原题链接 考察:主席树 思路: 利用二分的思想,即在主席树上二分,详细参考代码,主要记板子. 1 #include <iostream> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 using namespace
阅读全文
摘要:原题链接 考察:思维 思路: \(a^2+b^2=c^2\) \(a^2 = c^2-b^2 = (c+b)(c-b)\) \(令c+b = a^2 ,c-b = 1则\) \(c = \frac{a^2+1}{2} , b = \frac{a^2-1}{2}\) 此时分5种情况: (1) n =
阅读全文