2019.12.17
2019.12.18
codechef STICNOT
问题等价于给每条边和每个点分配一个权值,使得点权(geq)相邻边权
考虑将边权从大到小插入,插入第一条边的时候,我们也就确定了其两端的点的点权的最小值。接下来放第二条边的时候,肯定将其放在与第一条边有公共点的位置是最优的,因为公共点的点权一定是大于等于该边边权的,也就是这条边只确定了一个点点权的最小值。
一直做下去,问题就变成了第一条边确定两个点的最小值,之后每条边确定一个点的最小值,求最小修改数使其合法。直接贪心即可,最后还可以发现这个问题和树的形态结构无关
luogu5242 [USACO19FEB]Cow Dating
暴力就是求(sum_{i=l}^rp_iprod_{j=l,j eq i}^r(1-p_j))的最大值。
记(pro_i=prod_{j=1}^i(1-p_j)),则所求为(frac{pro_r}{pro_{l-1}}sum_{i=l}^rfrac{p_i}{1-p_i});再记(sum_i=sum_{j=1}^ifrac{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(NYsqrt 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}^ndbinom{n}{i}a^{(i)}b^{(n-i)})
记(P(x)=sum_{i=1}^kfrac{a_i}{x^i}),然后所求就是
根据(n-j)的奇偶性,将对(sin(x))与(cos(x))的贡献分开计算,然后发现剩下的是个喜闻乐见的卷积形式,NTT即可
luogu5643 [PKUWC2018]随机游走
首先minimax容斥一波,转为求至少经过某个给定集合的一个点的期望步数
之后你要知道一个套路叫树上高斯消元
假设当前状态(S)一定,记(f_u)为从(u)点出发,到达(S)中的某一个点的期望步数,首先有(uin S)时,(f_u=0);对于其它的(u),记每个点的度数为(d_u),有
之后根据树上高斯消元的那一套理论,把(f_u)写成(A_u imes 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=2nsum 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^{lceilfrac{L}{2} ceil}),再减去那些最小循环节比(L)还小的就行了,这部分是(sum_{x|L,x eq L}f_x),由于(nleq 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),实际上另一种情况大致相同):
- (jleq p1)
对答案的贡献为(sum_{j=mid+1}^{p1} mx*mn*(j-i+1)),直接计算.
- (p1<jleq 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^2leq 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(Bleq M,Cleq K)),所以剩下的(M-B+K-C)张牌任意是什么均可.接下来注意到翻开的(N+B+C)张牌中最后一张一定是(A),剩下的有(N-1)张(A),于是这里有一个组合数的贡献.写答案的时候注意到答案只和(B+C)有关,于是我们枚举(i=B+C)则答案就是
直接做显然是不行的,考虑优化,这里不要考虑拆组合数,注意到最后的组合数求和的式子一定是对一个区间([l,r])求(sum {ichoose 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分治