随笔分类 - NOIP、CSP提高组
摘要:传送门 解题思路 不得不说,这题恶心到我了,调了一个多小时。 第一次高精度把运算等写在struct里面,感觉良好。但是一定要注意初始化。 再就是高精乘高精最后的位数是两个位数相加,而不是相乘。 AC代码 #include<iostream> #include<cstdio> #include<cst
阅读全文
摘要:传送门 解题思路 遍历每个点,判断两个空洞之间是否能联通,若联通,则在两个点之间建一条边。 然后在能抵达上表面的点和能抵达下表面的点分别建边连向上表面/下表面,最后dfs判断上下表面是否联通即可。 总复杂度 AC代码 #include<iostream> #in
阅读全文
摘要:传送门 加强版传送门 解题思路 首先很显然,对于同一种色调的客栈来说,从小到大枚举左端点 L,符合要求的客栈 R~N 一定是满足 R 单调递增的。 而且选择的咖啡店也是随着 L 的增加间断着递增。 所以就可以双指针(准确说是多指针)将时间复杂度降至O(n)。 双倍经验双倍快乐 AC代码 #inclu
阅读全文
摘要:传送门 解题思路 很巧妙的一个题。 朴素的dp方程肯定都能列出来,关键是离散化如何操作。 可以仿照NOIP2017D1T1小凯的疑惑,将两个石头之间距离>=(st-s-t)全部转化为(st-s-t)。 可以理解为若距离>=(st-s-t),则所有的点都能到达。 但是这题要求宽松,方便又保险起见,把距
阅读全文
摘要:传送门 解题思路 首先明白题意: 能经过的点必须满足其所有连向的节点都能走到终点。 于是我们就可以建个反图,跑一遍dfs,求出有多少满足条件的点,最后bfs跑一遍即可。 如何判断? 用一个num数组表示节点i在原图的出度,即在反图的出度。 每当有一个点指向节点i时,num[i]--。 最后若num[
阅读全文
摘要:##传送门 ##解题思路 总体思路:二分W,对于每个W求得一个y,根据y-s的正负调整l和r,并且每次更新ans。 如何求y? 可以扫一遍矿石,用a数组记录下符合条件的数量的前缀和,b数组记录下符合条件的v的求点缀和;再枚举每个区间加起来即可。 ##AC代码 #include<iostream> #
阅读全文
摘要:##传送门 不得不说这题细节很恶心。 ##解题思路 二分最小时间x: 首先很显然的贪心是,每个节点的军队在时间x内一定要尽可能向上走,并且如果某个子树如果去支援别的子树,一定到的是子树的根节点(即根的儿子)。 所以我们可以用倍增判断在时间x内每个军队能到达的位置,把能到达根节点的并且还有剩余时间的拿
阅读全文
摘要:##传送门 比较综合的一道题。 ##解题思路 求把一条边变为0后这m条路径中的最短值,最大值最小,可以二分求解。 如何check某个答案x是否合法? 实质就是判断能否找到一条边,使得大于x的路径都经过这条边,并且减去这条边边权后路径长度都小于等于x。 于是我们先预处理出要求的路径的原长度(倍增求LC
阅读全文
摘要:##传送门 发现自己数论+文化课数学都已经炸了,所以从头学起补一补,以后要多刷数论题了。 ##解题思路 可以转换成 而答案就是这个方程的解中x的最小正整数解。 直接用exgcd算出一组解,然后想办法得到x的最小正整数。
阅读全文
摘要:传送门 解题思路 先遍历一遍树,求出size[u](节点u的所有相邻节点的点权和),和图中联合权值的最大值。 如何求最大值? 求出每个点相连的点的第一大和第二大点权,相乘后与ans取max。 再求和: 再遍历一遍树,对于每个点u,答案加上w[u]*(size[v]-w[u])。 AC代码 1 #in
阅读全文
摘要:传送门 解题思路 用dp[i][j][0/1]表示到第i节课、申请了j次,第i节课是否申请的最小体力和。 然后分别从dp[i-1][j][0]、dp[i-1][j][1],dp[i-1][j-1][0]、dp[i-1][j-1][1]疯狂转移过来。 先跑一边Floyd求最短路。 注意double无法
阅读全文
摘要:传送门 解题思路 每行互不影响,所以分开处理,对于每一行,很显然是个区间dp,我们用dp[i][j]表示区间[i..j]的得分和的最大值,注意每次加一个数的顺序是先加上数再集体乘2。 恶心的地方在于需要写高精(学校比赛懒得写,所以只拿了60分),需要一个高精度+int,一个高精度*2,一个高精度+高
阅读全文
摘要:传送门 解题思路 先说我的思路:枚举中间的那个人,然后在左边序列、右边序列分别做一次LIS,时间复杂度为n^3。 看题解后才发现有更优的做法,我们可以先预处理出正向和反向的LIS,然后枚举i统计答案即可,时间复杂度为n^2。 AC代码 1 #include<iostream> 2 #include<
阅读全文
摘要:传送门 解题思路 很显然的LIS板子题,找一个最长不上升子序列和最长上升子序列即可。 关于LIS(O(n^2)和O(nlogn)) AC代码 1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstdio>
阅读全文
摘要:传送门 解题思路 个人感觉难度应该在蓝题左右 (可能是我太弱了趴) 首先我们知道,那个所谓的头标记和尾标记,在合并区间[l...r]时,n和m是确定了的(即l的头标记和r的尾标记),只差中间的r,所以我们可以枚举k(断点)。 然后我们又可以得出,对于合并区间[l...r],最终得分为(dp[i][k
阅读全文
摘要:传送门 解题思路 对于整个中序遍历,做一遍区间dp: 枚举区间[l...r]内的所有节点作为根节点,然后计算出得分,若比当前的值要大,同时更新dp值和root[l][r](为了输出先序遍历)。 先序是根左右,所以递归输出就好了。 AC代码 1 #include<iostream> 2 #includ
阅读全文
摘要:传送门 解题思路 一道裸的dp。 用dp[i][j][k][kk]表示用i个1步,j个2步,k个3步,kk个4步所获得的最大价值,然后状态转移方程就要分情况讨论了(详见代码) 然后就是一开始统计一下几步的卡片共有几张存在num里。 这道题的范围小,所以可以大胆的用思维数组QAQ!!! AC代码 1
阅读全文
摘要:传送门 解题思路 就是暴力!!! 没什么好说的,总之,就是枚举每一个起点,然后暴力算一遍以这个点为起点的所有路径,在算的过程中,只要比目前找到的答案更优,就有可能是最后的答案,于是就把路径更新一遍,保证不错过正确答案。 由于数据很水<21,所以放心暴力! AC代码 1 #include<iostre
阅读全文
摘要:传送门 解题思路 一看数据范围<1000就坚定了我暴力的决心(不愧是1996年代的题还是t4QAQ) 所以很显然,暴力之中有一点dp的思想,就是把它们像多重背包一样拆分,拆成a1+a2+a3+a4+a5+a6个砝码,然后枚举一遍,如果vis[j]是1也就是j这个数值可以被表示的话,那么vis[j+a
阅读全文