退役前的做题记录
2019.12.17
2019.12.18
codechef STICNOT
问题等价于给每条边和每个点分配一个权值,使得点权\(\geq\)相邻边权
考虑将边权从大到小插入,插入第一条边的时候,我们也就确定了其两端的点的点权的最小值。接下来放第二条边的时候,肯定将其放在与第一条边有公共点的位置是最优的,因为公共点的点权一定是大于等于该边边权的,也就是这条边只确定了一个点点权的最小值。
一直做下去,问题就变成了第一条边确定两个点的最小值,之后每条边确定一个点的最小值,求最小修改数使其合法。直接贪心即可,最后还可以发现这个问题和树的形态结构无关
luogu5242 [USACO19FEB]Cow Dating
暴力就是求\(\sum_{i=l}^rp_i\prod_{j=l,j\neq i}^r(1-p_j)\)的最大值。
记\(pro_i=\prod_{j=1}^i(1-p_j)\),则所求为\(\frac{pro_r}{pro_{l-1}}\sum_{i=l}^r\frac{p_i}{1-p_i}\);再记\(sum_i=\sum_{j=1}^i\frac{p_j}{1-p_j}\),则所求为\(\frac{pro_r(sum_r-sum_{l-1})}{pro_{l-1}}\).
假设当前最优解区间为\([l,r]\),固定左端点,将右端点向右移时若要使得答案更优,整理可以得到\(sum_r-sum_{l-1}<1\)。枚举\(l\)同时维护最右的指针即可。注意开long double
luogu5243 [USACO19FEB]Moorio Kart
对每棵树找出所有的路径长度方案数和该长度的所有方案的长度和。之后暴力dp合并,注意中间省去每棵树种不存在的长度貌似可以做到\(O(NY\sqrt Y)\).最后乘上圆排列的系数
CF1266D Decreasing Debts
要使\(\sum d\)最小每个人只能有一条出边或一条入边。同时再加上可以随便指,便可以预处理出每个人最终的收支情况,支出的向收入的连边即可
CF1266E Spaceship Solitaire
所有的优惠方案都是一定可以达成的,map维护\((s,t,u)\),每次修改的时候暴力\(+1\)或\(-1\)即可
luogu4377 [USACO18OPEN]Talent Show
首先01分数规划,之后记\(f_i\)表示\(\sum w=i\)时的最大权值和。注意到\(\sum w\)至多在\(W=1000\),大于的直接看做\(W\),于是直接01背包就完事了
luogu4376 [USACO18OPEN]Milking Order
二分答案+toposort判断是否合法,最后拿优先队列再跑一遍toposort求答案,注意二分答案的时候使用普通的queue使得复杂度是一个\(\log\)的
luogu4374 [USACO18OPEN]Disruption
将所有的新边按照边权从小到大排序,注意到对每条新边\((u,v,w)\),只有原树中删去在路径\((u,v)\)上的边的时候才能把这条边加入从而形成一棵新树。于是暴力并查集合并就可以了(类似于LOJ3040的合并方法)
2019.12.19
咕咕咕
2019.20.20
某个noi集训的day6t1
首先你要知道\((ab)^{(n)}=\sum_{i=0}^n\dbinom{n}{i}a^{(i)}b^{(n-i)}\)
记\(P(x)=\sum_{i=1}^k\frac{a_i}{x^i}\),然后所求就是
根据\(n-j\)的奇偶性,将对\(sin(x)\)与\(cos(x)\)的贡献分开计算,然后发现剩下的是个喜闻乐见的卷积形式,NTT即可
luogu5643 [PKUWC2018]随机游走
首先minimax容斥一波,转为求至少经过某个给定集合的一个点的期望步数
之后你要知道一个套路叫树上高斯消元
假设当前状态\(S\)一定,记\(f_u\)为从\(u\)点出发,到达\(S\)中的某一个点的期望步数,首先有\(u\in S\)时,\(f_u=0\);对于其它的\(u\),记每个点的度数为\(d_u\),有
之后根据树上高斯消元的那一套理论,把\(f_u\)写成\(A_u\times f_{fa}+B_u\)的形式,则有
根节点没有父亲,\(f_{rt}=B_{rt}\),其它的一遍\(dfs\)搞定
在求答案的时候,可以暴力\(O(q2^n)\)统计答案,或者搞个\(fwt\)求子集和做到\(O(n2^n)\)
luogu5465 [PKUSC2018]星际穿越
考虑对每个点的最优方案一定是先至多往右走一步,再一直往左跳跳跳;并且最终的答案一定具有单调性。
用数学的语言就是,从第二步开始,假设当前可以在的最小的点为\(x\),那么经过这一步可以跳到的最小的点为\(min_{i=x}^n(l_i)\),证明的话自己画一下图就完事了
之后就可以大力倍增了,\(f[i][j]\)表示最小值为\(i\)时跳了\(2^j\)步能到的最小值,\(g[i][j]\)表示从\(i\)到\(f[i][j]-i\)中的所有点的距离和
2019.1.20
Codeforces 734F
一个经典结论是\(a\&b+a|b=a+b\).
那么\(b_i+c_i=\sum_{j=1}^na_i+a_j=na_i+\sum a\)
把所有的\(b,c\)加起来就有\(\sum b+\sum c=2n\sum a\)
然后就能把\(a_i\)全部搞出来,然而这只是必要条件,还需要把\(a_i\)倒回去看一下是否合法.
2019.1.21
Codeforces 464E
直接写高精度显然会gg
冷静一下发现我们的高精度只需要支持\(+\)和\(>\)两种运算,再加上所有的边权都是\(2^x\),便可以像NOI2017那样用线段树来维护dij中的\(dis\)数组.
\(+\)的话直接把线段树写成主席树,同时注意到二进制加法等价于将从这一位开始的一连串\(1\)变成\(0\),再把下一位变成\(1\),于是直接线段树上二分即可.
\(>\)的话可以考虑维护每个区间的hash值再线段树二分
ARC064D
不难发现结束时串的形态只和\(s_1\)与\(s_n\)是否相等有关.
若\(s_1=s_n\)则最后的串一定形如\(ababa...ba\),反之即为\(abab...ab\),不难发现无论是哪一种删去字母的奇偶性都是确定的,分类讨论即可
ARC064F
对每一个回文串,它的贡献只与它的最小循环节的长度\(L\)有关,若\(L\)为奇数那么它就有\(L\)的贡献,若为偶数则有\(\frac{L}{2}\)的贡献,这个画一下就能得到了.
之后的就是记\(f_L\)为最小循环节为\(L\)的回文串的个数,发现循环节为\(L\)的回文串的个数为\(k^{\lceil\frac{L}{2}\rceil}\),再减去那些最小循环节比\(L\)还小的就行了,这部分是\(\sum_{x|L,x\neq L}f_x\),由于\(n\leq 10^9\)时\(\sigma_0(n)\leq 1344\),于是直接\(O(n^2)\)即可.
2019.1.22
ARC058E
答案的计算可以先统算不合法序列的个数再用\(10^n\)减去,发现\(x+y+z\)很小可以状压,记\(f_{i,sta}\)表示长度为\(i\)的,后缀和的状态为\(sta\)的方案数,其中\(sta\)上第\(k\)位的\(1\)表示存在\(k\)的后缀和,显然\(k\)至多是\(x+y+z\).转移的话枚举下一位是什么,同时更新\(sta\)即可.
2019.1.23
ARC059D
一开始把问题归结成了找一个和\(>0\)的区间,之后发现自己sb了.只需考虑长度为\(2,3\)的合法区间即可.不难证明长度\(k>3\)的合法区间一定包含了长度为\(2,3\)的区间.
luogu5899 [COCI 2015]Norma
如果只有\(\min/\max\)的话显然可以每次找到当前区间的最值分治.但是如果两者同时存在的话分治的时间复杂度就会爆炸.
考虑cdq分治,我们枚举\([l,mid]\)中的\(i\)作为左端点,记\(mx,mn\)分别为\([i,mid]\)的最大/最小值,同时维护\([mid+1,r]\)中的两个指针\(p1,p2\),使得\(\min_{mid+1}^{p1}(a_i)>=mn,\max_{mid+1}^{p2}<=mx\),且保证\(p1,p2\)最大化.之后就是枚举区间右端点\(j\)大力分类讨论(这里保证\(p1<p2\),实际上另一种情况大致相同):
- \(j\leq p1\)
对答案的贡献为\(\sum_{j=mid+1}^{p1} mx*mn*(j-i+1)\),直接计算.
- \(p1<j\leq p2\)
对答案的贡献为\(\sum_{j=p1+1}^{p2}mx*\min[mid+1,j]*(j-i+1)\)
即\(\sum_{j=p1+1}^{p2}mx*\min[mid+1,j]*j-\sum_{j=p1+1}^{p2}mx*\min[mid+1,j]*(i-1)\).预处理\(\min[mid+1,j]*j\)与\(\min[mid+1,j]\)即可.
- \(j>p2\)
对答案的贡献为\(\sum_{j=p2+1}^rmax[mid+1,j]*min[mid+1,j]*(j-i+1)\).类似的预处理出\(max[mid+1,j]*min[mid+1,j]*j\)与\(max[mid+1,j]*min[mid+1,j]\)即可.
2019.1.24
ARC060D
肯定只能暴力枚举然后check了,于是问题变成了如何剪枝.
注意到最后会有大量的\(b\)使得\(n\)的\(b\)进制表示的长度很小,如果这个长度\(\leq 2\)那么肯定有\(b^2\leq n\),接下来解个方程就能发现\(b|n-s\),于是复杂度就变成了\(O(\sqrt n)\)
ARC060F
首先答案肯定和原串的最小循环节的长度\(L\)有关,若\(L=1\)则最优划分一定是\(N\)个串(每个串为1个字母记最小循环节),如果\(L=n\)则最优划分就是原串.以上两种情况的方案数均为\(1\).
对于剩下的情况不难发现至少存在一种划分成\(2\)个串的最优划分(否则与最小循环节的定义相矛盾),枚举端点判断是否合法即可,需要正反跑两遍kmp.
2019.1.25
ARC061E
拆点,把每个点拆成\(\max(c_i)\)个点,一条边\((u,v,c)\)可以表示成\((u,u',1)->(u',v',0)->(v',v,1)\),其中\(c\)相同时\(u'\)相同,跑dij即可,最后得到的ans要除以\(2\).
ARC061F
显然翻出来的牌一定是\(N\)张\(a\),\(B\)张\(b\),\(C\)张\(c(B\leq M,C\leq K)\),所以剩下的\(M-B+K-C\)张牌任意是什么均可.接下来注意到翻开的\(N+B+C\)张牌中最后一张一定是\(A\),剩下的有\(N-1\)张\(A\),于是这里有一个组合数的贡献.写答案的时候注意到答案只和\(B+C\)有关,于是我们枚举\(i=B+C\)则答案就是
直接做显然是不行的,考虑优化,这里不要考虑拆组合数,注意到最后的组合数求和的式子一定是对一个区间\([l,r]\)求\(\sum {i\choose B}\),且当\(i\)变化至\(i+1\)时,左右端点至多变化\(1\),于是按照杨辉三角的递推式我们可以快速维护后半部分.时间降至\(O((M+K)\log(M+K))\)或\(O(M+K)\)
2020.1.28
ARC065E
考虑题目所求,发现可以将距离为\(D\)的两点之间连一条边,转化为求\(a,b\)所在连通块的大小.
经典套路:对于一类有曼哈顿距离作为限制条件的题目,考虑旋转坐标系,即将点\((x,y)\)映射至\((x+y,x-y)\),可将曼哈顿距离转为切比雪夫距离.
在这个题中,转化为切比雪夫之后,记原来两点的距离为\(D\),那么问题转化为在新图中求两点\(i,j\)使得\(|x_i-x_j|=D,|y_i-y_j|\leq D\)(交换\(x,y\)同理).不难发现在按\(x\)排序后,合法的点是一段区间,可以线段树优化连边.
但事实上我们只需要考察这个图的连通性,于是从\(i\)连边的时候可以从与\(i-1\)连边的最后一个点开始接着连,同时记录\(i\)原本应连的边的条数,之后再交换坐标做一次.
注意细节:对于\(|x_i-x_j|=D,|y_i-y_j|=D\)的点不能统计两次,其它的看code吧.
ARC065F
我们将\(l_i\)相同的\(r_i\)取\(\max\).之后不难发现对于当前的修改区间\([l,r]\),\(l-1\)及之前的数都是已经确定的.
记\(f_{i,j}\)表示\(i-1\)以及之前的都已经确定了,当前(即考虑区间\([l_i,r_i]\)后)还有\(j\)个\(1\)可以使用.每次算出新增加的\(1\)的个数后枚举\(i\)位填什么进行转移.
2020.2.1
CF848C
对某个区间\([l,r]\),记某个数字\(m\)分别在\(a_1,a_2,...,a_n\)这\(n\)个位置上出现了,那么该数字贡献就是\(a_n-a_1=\sum_{i=1}^{n-1} a_{i+1}-a_i\)
记位置\(i\)上的数上一次出现的位置是\(pre_i\),那么对每次询问有
加上时间一维后就是三维,标准的cdq分治