- 博客(76)
- 收藏
- 关注
原创 [cf1599C]Bubble Strike
当我上线看到自己的problemset莫名其妙多了一个没通过的提交,就知道队友又瞎报比赛然后没空打于是摆烂了……一共n张图,每次系统随机选三张,两个玩家独立选其中一张叉掉,系统从剩余的图中随机选一张开。你已知自己熟悉哪些,而你的对手随机选择,问你至少研究几张可以保证有不小于p的概率开到你熟悉的图。假设n张图,m张我们熟悉的,概率是。所以从小到大枚举m,输出第一个≥p的即可,不预处理组合数也可以。可能的边界条件我直接全部单独判断了一遍。所以说咱真的不知道队友写了些什么#include<
2021-10-23 10:25:57
288
原创 [cf1599f]Mars
题意:给一个模1e9+7下的长度为n的序列,有q个询问,问对于区间[Li, Ri],是否能将其排列成一个模1e9+7意义下的,公差为Di的等差数列?对于这个验证方法有些很奇妙的思路……也许是套路吧,我太菜了,不太熟。我们可以求得原序列的前缀和,得到Si = sum(Li...Ri)。令len = Ri - Li + 1, 假如说我们能构造出一个等差数列,那么应该有Si = len * A0 + len * (len - 1) / 2 * Di。所以我们可以用Si和Di算出一个A0,那么这个等差数列的
2021-10-23 09:41:33
266
原创 [cf1599G]Shortest path
题意:给n个点,其中n-1个共线,指定一个起点,每次可从一个点沿直线移动至另一个点,点可重复访问,问访问过所有点至少一次的最短路径。首先我们肯定要找出不共线的那个点。按x坐标将n个点排序,计算出所有相邻两点的斜率,只要点数大于等于四,那么和其它不同的两个斜率之间的点就是不共线的点。(仅有三个点的情况直接算一下就好。)为了方便起见,我们可以重新排个序,将不共线点放到最后,1到n-1为有序的共线点。显然,如果没有不共线点,那么我们肯定始终沿直线移动,故不共线点仅会被访问一次。以及,进行多次折回显然无意义
2021-10-23 09:17:26
333
原创 [cf1592E]Bored Bakry
题意:给出一个序列,找出长度最长的位置区间,满足区间内其中所有元素按位与之和等于异或和,输出该长度。首先长度肯定为偶数。如果是奇数,某一为按位与结果为1则必有异或结果为1,故与和不大于异或和,故不可能为奇数。对于一个区间,如果我们能找到一个二进制位k,满足区间内所有数在该位均为1,且大于等于该位的部分异或和为0,则这个区间是满足要求的。所以先枚举k,再从1到n循环一边序列,求不低于k的位数的异或前缀和,记录最近一个第k位为0的数的位置。根据这些信息,分奇偶记录在当前k为1的区间内,最远的异或前缀
2021-10-19 20:17:57
276
原创 [cf1592d]Hemose in ICPC ?
简单交互题。题意是给出一棵树,边权未知,定义一条简单路径的长度为路径上所有边边权的gcd。你每次可以询问一个点集,返回给你由这个点集内点构成的所有简单路径长度的最大值。你要找到长度最大的简单路径的两个顶点。显然由单条边构成的路径长度大于等于它加上其他边构成更长的路径。所以我们只要把树建出来,把n-1条边按dfs序排序,二分询问即可。#include<cstdio>#include<cstring>#include<algorithm>#define l
2021-10-19 18:39:44
294
原创 [cf1599A]Weights
比赛前不摸了不摸了,爬起来做题了,开个做题记录。题意是给一个序列,再给一个LR组成的字符串。要求将序列随意排序后,每次向天平一端加上你排序后序列的第i个数,天平倾斜情况符合给出的字符串。构造题。主要是需要注意到:当我们将一个从小到大排好序的序列交替左右放置,下沉的一端一定是最后放上数的那端。证明的话可以分奇偶讨论一下。设字符串转折点(L->R或R->L)共有x个(假设包含第一个),那么我们先将原序列排序,最大的x个数按顺序填到这些位置里(显然是放到下沉的那边)。然后考虑怎样把剩下
2021-10-19 18:29:12
291
原创 [cf1537F] Figure Fixing
由于每次同时给两个点加k,所以若初始v[i]的和与t[i]的和奇偶性不同则一定不能。然后考虑如果是二分图。好像对于图论题,这种看不出什么的时候经常会考虑:如果是二分图则balabala...二分图总有些优秀的性质叭。那么把点黑白染色一下,每条边连接一黑一白,也就是说每次修改点值会分别给一个黑点一个白点加上k。那么初始情况下,黑点v[i]-c[i]之和与白点v[i]-c[i]之和必须相同才有可能行。又因为图的连通性,所以两边只要相同就一定可以都变成0。在此基础上考虑不是二分图的情况,也就可以转化为比一
2021-07-05 20:30:46
326
1
原创 [cf1536F] Omkar and Akmar(组合数)
我们先考虑一下什么情况游戏结束。这个题题意是两个人都可以放A或者B的。因为两个A不能相邻,所以当不能再放A时,如果棋盘上存在两个A之间没有B,他们只可能间隔1个或2个位置,否则就可以继续放A,且这两种情况,都可以在空位再放一个B,不能再多。AB交换同理。所以有一个A它旁边就有一个B,最终一定是某种AB交替的情况,且AB数量相等。进一步还有,每两个字母之间只可能没有或有一个空位。我们发现了这是个后手必胜的游戏。但对这道题好像没什么用。棋盘最多可以放下组AB,最多组。而对于放i组的不同游戏数量,就是在n
2021-07-05 20:12:39
143
原创 [cf1535E]Gold Transfer(树上倍增)
由于父节点的c值一定小于子节点,所以对于每次询问,我们需要找到询问节点v到根的路径上,深度最小的、a还有剩余的节点,从该节点开始购买,买完一个点再买他的子节点,直到结束。由于每个节点只会被买完(其a值改为0)一次,且当它的a为0时,它到根路径上所有点一定已经为0,所以可以用倍增方法寻找最浅不为0的点。就是先尝试向上跳2^k层,如果该点为0,则不跳,继续试跳2^(k-1)层;如果不为0,则跳到那个点,也继续再试2^(k-1)层。如果买完了这个节点,我们无法直接找到该路径上下一个节点,所以需要继续做倍增,直
2021-07-05 19:48:06
240
1
原创 [cf1536E]Omkar and Forest
题意:给一个矩形,0即代表该位置为0,#代表未知,可填任意正整数。相邻两位置最多差1,任何正整数一定比它四周至少一个位置大。求有几种填法。感觉有点有趣。0和正整数的限制不太一样。如果#只能填正整数,那么思考一下发现填法唯一——是个bfs过程,所有0相邻位填1,再所有1相邻位填2……直至填满。因为任何正整数一定比一个相邻位置大,所以不能往回填;又因为绝对值最大为1,所以只能每次加一。现在#可以填0或正整数。那么就是在所有#中选任意多个填正整数,有几种选法就有几种填法,显然答案为2^k(k为#数)。
2021-07-02 17:29:57
119
原创 SEERC2020练习
按照蒟蒻做题顺序来写的。M. Mistake题意是有k组1-n的数,每组都满足m对先后次序关系,保持组内顺序不变地把k组混在一起,要求输出每个数来自第几组
2021-06-01 00:12:40
736
1
原创 [cf1485c]Floor and Mod(数论)
题意很简单,就是要求满足a=kb+k(0<k<b)的(a,b)的数量,且1≤a≤x,1≤b≤y。目测是个很可搞的数学题,那么我们来胡乱分析一波。假如没有k<b的限制。对于处于1到y范围内的每个b,它的贡献就是x/(b+1)。这个是可以用整除分块做的。以防有人不知道(没有什么是整除分块呢?就是因为从1到y枚举b肯定是不显示的,但我们可以注意到,因为这里的除是要向下取整,所以其实对于一个区间内的b,x/(b+1)的值应该都是一样的。那么我们只需要对于每个区间左端点计算出x/(b+1
2021-02-13 10:15:30
773
1
原创 [cf1485e]Move and Swap(dp)
看起来很像树形dp,如果没有交换操作的话,显然有dp[u]=max(dp[v])+max(abs(a1[u']-a1[u]))其中v为u的儿子,u'与u处于同一深度。然后考虑交换操作可能会怎样影响结果。假如是u'和u交换,用于更新dp[u],那么计算出的结果应该是dp[u]=max(dp[v'])+abs(a1[u']-a1[u])。这样思路就有了,连边后首先做一次深搜,记录每个节点的深度,每层的最大值和最小值。再将节点按深度从大到小排序做,因为由上面第二个方程可以看出,我们不仅需要每个节点最大儿子
2021-02-13 09:55:36
1303
原创 [agc047D]Twin Binary Trees
首先纯暴力就是L²枚举每组叶子节点,然后两边分别一路跳到lca来统计,复杂度O(HL²)。然后我们考虑可能在哪里优化。可能有很多组叶子节点,他们构成的环在上下两部分里lca都是相同的,那就可以合在一起统计。那其实可以当走完一条这样的路径(也就可以看作一个环的一半)时,用乘积和之前这个点存储的结果做乘,加到最终结果,再把当前乘积加到该点中。复杂度O(LH²)。所以就转换成枚举上部的lca,以他为最上端的环必然左边在它左子树里,右边在右子树里,所以要分别枚举左右子树的点。先说左端记录过程,对于每个点,我
2021-02-12 16:51:55
227
原创 [cf1473e]Minimum Path(分层图最短路)
是个分层图的问题。感觉知道的话似乎很容易就想到了,不知道的话……大概就不知道了qwq。分层图就是说,如果在一个带权图上,我们对于每条路径都可以将其中k条边做一些改变,比如不计算其权值,那么我们就先建k+1层完全相同的初始图(权值为原值),然后层之间的连边情况不变,但权值为改变之后的。比如如果图是1、2、3两两之间连一条权值为1的边,一条路径上可以有一条边不计算权值,求1到各点最短路。那么我们建图分两层,一层的1、2、3两两间连边权值为1,二层的1'、2'、3'两两间连边权值为1,然后1->2'
2021-01-17 19:38:00
358
原创 [cf1215f]Radio Stations(2-SAT)
题意就是有p个点,可以选取或不取。有n对关系,满足两者至少取一个。又有m对关系,满足两个不能同时取。同时每个点有区间[li,ri],最终要满足存在这样一个数属于所有取到点的区间,也就是说他们的交集不是空集,并且已知li、ri∈[1,M]。如果不看最后区间的限制条件的话,就是裸的2-SAT了。对于n对关系,将不取a向取b连边、不取b向取a连边;对于m对关系,取a向不取b连边、取b向不取a连边。然后我们考虑如何通过连边描述每个点的区间。一个点的左端点所限制的其实是:如果最后选取的数小于li,那么是不能取
2021-01-16 21:13:11
194
原创 [cf1406D]Three Sequences(线段树+差分)
给一个序列a,要得到两个数列b和c,使bi+ci=ai,且b序列递增,c序列递减,要使b和c中最大元素最小。同时会有q次修改,每次将a序列在(l,r)区间内的元素都加上x。首先由于b和c的性质,所以使b和c中最大元素最小,即是使max(bn,c1)最小。然后我们假设c1已确定,这样b1就也被确定,考虑能否确定b2和c2。由于要使bn最小,所以尽量使每个bi - bi-1尽量小,由于ai和ai-1已经固定,所以(bi - bi-1)+(ci - ci-1)已固定,等同于使ci-1 - ci尽量小。那么每次
2020-10-03 15:19:33
159
原创 [cf1405E]Fixed Point Removal(平衡树+树状数组)
编号为1-n的纸牌,按一定顺序排列,每次可以移走放在第i个且编号为i的纸牌,右边的自动向左补齐。每次询问限定了左边x张和右边y张不能动,问最多移走多少张。好像和电脑里的“纸牌”有点像?为了移走尽量多的话,如果同时有多张可以拿,显然应该先拿最右边的,这样保证其他已经可以被拿的牌不受影响,且可能产生更多能被拿走的牌。每次先拿走一张,之后右边所有牌序号-1,这个操作似乎让我们想到了平衡树。如果不考虑多次有限制的询问,只考虑原始序列能拿走多少张,显然简单的平衡树操作就可以处理。考虑如果有限制,会影响拿牌
2020-09-09 10:14:27
359
原创 [cf420D]Cup Trick(平衡树)
题目还是比较直接的。模拟一下过程然后发现,只要从后向前做,一开始每个节点都为0,每次找到第一个节点,标记为xi,把它从平衡树上分离,再插到第yi-1个节点后面即可。如果要标记的节点已经不为0,且不等于xi,输出-1;如果xi已经在平衡树中,且不是第一个节点,输出-1.#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=1000010;stru
2020-09-06 09:49:35
265
原创 [cf150E] Freezing with Style(点分治+二分)
这个中位数显然可以通过二分来确定。检验的方法就是把边权大于等于检验值的设为1,小于的设为-1,看是否有一条路径边权和大于等于0。关于长度的限制则可以用点分治。对于节点u,先把它的子节点按子树从小到大排序,保证复杂度,开个桶记录一下长度为d的边最大的权值bkt[d].w,以及其端点bkt[d].x,然后逐一合并。到子树v时,先dfs一下,求出子树内的不同长度下最大权值,用t1数组记录一下,然后对于t1内每个值,需要寻找一个滑动区间内的最大值,类似于单调队列的思路。若没有找到可行解则把t1合并到bkt中,再
2020-09-04 12:22:57
165
原创 [P2607][ZJOI2008]骑士(基环树)
边数等于点数,是基环树。考虑dp,如果是树的话,转移方程为dp[u][1](选择u)=w[u]+Σdp[v][0],v为u的子节点; dp[u][0](不选择u)=Σmax(dp[v][0],dp[v][1])。然后基环树只要找到环后,断开环上的一条边就成了树。断开的边上两端点不能同时选择,所以对于每棵基环树,我们求两边dp,分别限制两个端点必须不选,然后取最大的结果。每棵树答案相加即为最终答案。#include<cstdio>#include<cstring>#inclu
2020-08-30 18:28:54
234
原创 [P3233][HNOI2014]世界树(虚树)
看到∑mi≤300000自然联想到虚树,简单思考一下似乎可行,但剩下的部分貌似就比较麻烦。首先对重新构建的虚树,考虑每个点应该被谁管。因为一个点既可以被它子树中的点管,也可以被子树以外的点管,所以我们做两次dfs。第一次先遍历子节点,再更新,记录的是一个点子树中最近的管他的点是谁。第二次先用从父节点得到的数据更新,再遍历子节点,是把子树之外可以管他的点也考虑进去。在第二次dfs时我们可以顺便统计一部分贡献,就是对于节点i,如果它其中一个子节点的子树不在虚树内,那这棵子树中一定没有可以管别人的点,那么显
2020-08-29 20:15:09
139
原创 [P1600][NOIP2016]天天爱跑步(lca+桶+差分)
填一下退役前(被我遗忘)的坑……读完题后首先想到的模拟过程,大概就是对于每个玩家的路径,一个点一个点地验证能否被观测到,把贡献加给该点。要想写部分分的话,看到有一些数据s=1,也就是从根节点出发,那么只要路径上的点的深度(假设根节点深度为0)等于w值即可,于是可以给我们一个思路,一条路径上的点i能否被观测到,可由dep[i]和w[i]与这条路径的关系确定。那么关系式长什么样呢?显然应该分成两部分考虑,由s到lca和由lca到t。稍微画几个图推一推可以发现,前半段观测条件为dep[i]+w[i]=
2020-08-29 11:09:15
209
原创 [P2494][SDOI2011]保密(整体二分+拓扑排序+最大流)
这道题其实分为两步:1.求出从点n到点1~n1的最短距离,也就是ΣSi/ΣTi(i为路径上的点)的最小值。 2.求出能到达所有空腔的距离之和的最小值。 我们逐个来考虑。对于第一步,我们可以看到每个点的答案都在0.1到10.0的范围内,考虑整体二分。(然后发现蒟蒻不会整体二分,赶快临时学习一下…)如果某个点的最短距离小于等于当前尝试的解,即有ΣSi/ΣTi<=x,整理后即为ΣSi-ΣTi*x<=0。所以我们每次把边权设为s-t*x,求从n点出发到1~n1点的最短路。注意到题中保证没有环,所..
2020-08-23 17:42:52
204
原创 [poj3020]Antenna Placement(二分图最大匹配)
这种上下或左右相邻的问题可以考虑黑白染色法。横纵坐标相加为奇数的染黑,偶数染白,这样每个点和四周的四个点颜色不同,建边后就形成二分图。先假设每个*都要放天线,然后最大匹配显然就是可以省掉的天线数,一减即可得到答案。#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int H=50,W=20,N=210;int t,h,w,cnt,num1,num2,v
2020-08-22 22:49:39
137
原创 [poj3041]Asteroids(二分图最大匹配)
求最小顶点覆盖,即求二分图最大匹配。可以一下消除一行或一列,属于行列匹配法。#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=510;int n,k,cnt,map1[N][N],mat[N],vis[N];inline int read(){ int x=0;char ch=getchar(); while(ch<'0'||c
2020-08-22 22:43:48
93
原创 [fzu2271]X(Floyd)
跑Floyd的时候,如果k能够更新(i,j),且(i,j)间有边,则可以砍掉的边数+1。要注意可能有重边,一开始建图的时候就要判。#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=110,inf=0x3f3f3f3f;int dis[N][N],pas[N][N],n,m,cnt,t;inline int read(){ int x=0
2020-08-18 22:40:41
95
原创 [poj2296]Map Labeler(二分答案 + 2-SAT)
由于每个点只可能位于正方形上边中点或下边中点,考虑2-SAT。我们可以按纵坐标升序给点排个序。若已知正方形边长为x,首先如果两个点横坐标差大于x,那么无论如何也不会覆盖。否则,计算两点纵坐标之差:1.为0,则必一上一下 2.大于0且小于x,则只能前一个点向下盖,后一个点向上盖 3.大于x小于2*x,则前一个点向上盖时,后一个必向上;后一个向下时,前一个必向下点的个数不多,二分法每次验证一个值可不可行时通过枚举点对重建一次图。#include<cstdio>#include<..
2020-08-17 22:54:13
108
原创 [P3469][POI2008]BLO-Blockade(tarjan+割点)
原图保证是连通的,要求把点u的所有连边断掉后,不能互相到达的点对数(有序)。分析可得,断掉边后图由一个u点与几个连通块组成,u不能到达剩余n-1个点,一个大小为x的连通块内每个点都不能到达剩余n-x个点,它的贡献为x*(n-x),总和即为u点的答案。跑tarjan的过程其实类似于形成一棵树,跑到能成环的边时对应dfn[v]!=0。假如无环,那么断掉点u连边后形成的连通块,即为它的所有子树和整体除去以u为根节点的子树的那部分,维护每棵子树的大小可轻易得到。当low[v]<dfn[u]时,证明u的子树
2020-08-15 16:42:07
123
原创 [P3975][TJOI2015]弦论(后缀数组)
时隔一年再回归w这题用后缀数组来做的话,主要就是t=1时比较麻烦。考虑可以想办法得到一个前缀和,求出到排名为i的后缀一共有多少子串。之后再二分找到第k个子串在哪个后缀里。求前缀和时,对于相同的子串,要在排名靠后的后缀长度中减去它,同时全部加到包含该子串的排名最靠前的后缀中。这个操作可以利用单调队列完成,既要更新一个后缀中包含的子串数目,也要同时记录每个有重复的子串长度和重复次数。二分找到包含目标子串的后缀后,用先前记录的重复子串情况,对该后缀从后向前逐位找到目标子串右端点。稍微注意一下long
2020-08-14 20:30:32
192
原创 [P4301][CQOI2013]新Nim游戏(线性基)
Nim游戏的结论为,当目前所有数字异或和不为零是先手必胜,必胜策略为使得操作后的异或和为0。所以如果在这个题目下后手想赢,就要拿完后使异或和为0,所以先手就要使后手无法做到这个操作,也就是说使第一轮拿完后,任意几堆火柴数量的异或和都不为零。用贪心的思想,把数从大到小排序。对于一个数,如果能插入线性基则插入,不能则添加到答案中。对于一个位置,先用大数占上而拿走之后的小数,最后答案就会比较小。...
2019-07-11 17:04:45
109
原创 [P1646][国家集训队]happiness(最小割)
建图,使源点为文,汇点为理,初始总喜悦度减可获得的最大喜悦度相当于图的最小割。先从源点向每个人连流量为选文喜悦度的边,且从每个人向汇点连流量为选理喜悦度的边。然后对于没一组相邻的同学都单独建一个点,若是同选文,就从源点向该点连流量为额外喜悦度的边,且从该点向其所代表的两个人连流量为无线的边,选理道理相似。这样保证了只要任意一人不选该科,就不会获得额外喜悦度。然后跑最大流即可。#inclu...
2019-07-08 15:01:42
180
原创 [P2664]树上游戏(树上差分)
考虑对于每种颜色,如果把该颜色的节点全部删去的话,会形成很多小的树。对于一个仍然保留的节点,除了与它在同一颗小树上的点,其余点都会对它产生1的该颜色的贡献。那么一个节点的sum就是总颜色数*总节点数-Σ删掉每种颜色后该节点所属的树的大小。于是考虑如何求新的树的大小,可以使用差分。对于一个颜色为c的节点u,它的儿子v的sum,便加上以v为根,最大的不含c颜色的树的大小。当在从v向它子树的某条路径...
2019-07-07 15:55:19
261
原创 [P3187][HNOI2007]最小矩形覆盖(旋转卡壳)
用旋转卡壳做。先求出凸包,枚举每一条边作为矩形的一边。画画图可以看出另外三个点的决策应该是单调的。对面的点用叉乘看三角形面积大小判断,两边的点用点乘看向量在已固定的边上投影的长度(即矩形的宽)判断。注意第一次的两侧定点应分别从对面定点的两侧开始判断,需要赋初值。然后用点到直线距离,两直线交点等数学运算求一求就好了。具体看代码注释吧。最后需要避免因精度问题输出-0.00000,所以整体加一个eps。...
2019-07-04 15:02:38
206
原创 [P3256][JLOI2013]赛车(单调栈)
对于两辆速度不同的赛车,快的早晚可以超过慢的,超过的时间就是他们初始距离差除以速度差。如果一辆车在超过比他慢的前一辆是就被比他快的后一辆超过了,或者不如比他快的初始位置远,他就永远不会成为第一。所以可以以速度为横坐标,初位置为纵坐标,将车按速度从小到大排序,超过的时间就是斜率的负值。然后单调栈维护一下斜率递减就可以了,可以用叉积来验证。#include<cstdio>#incl...
2019-07-03 08:01:13
167
原创 [P2600][ZJOI2008]瞭望塔(半平面交)
先在一个无穷高的位置画一条线为上界,把左右两端点向上连,形成一个封闭的多边形,求半平面交找到瞭望塔顶可以在的区域。因为点和点都是以直线连接的,斜率固定,所以半平面交到底边距离最近的点一定是某个拐点。那么把得到的集合内的线两两求一下交点,在从左到右依次求半平面交或是底边上的拐点到另一边的距离,找出最小值就可以了。#include<cstdio>#include<cmath&...
2019-07-02 21:15:56
139
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人