退役前的做题记录

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}\),然后所求就是

\[(P(x)sin(x))^{(n)}=\sum_{j=0}^n\dbinom{n}{j}(sin(x))^{(n-j)}P(x)^{(j)}=\sum_{j=0}^n\dbinom{n}{j}(sin(x))^{(n-j)}\sum_{l=1}^k\frac{(-1)^ja_l(l+j-1)!}{x^{l+j}(l-1)!} \]

根据\(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=\frac{f_{fa}+\sum_{v\in son_u}f_v}{d_i}+1 \]

之后根据树上高斯消元的那一套理论,把\(f_u\)写成\(A_u\times f_{fa}+B_u\)的形式,则有

\[A_u=\frac{1}{d_u-\sum_{v\in son_u}A_v},B_u=\frac{d_u+\sum_{v\in son_u}B_v}{d_u-\sum_{v\in son_u}A_v} \]

根节点没有父亲,\(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\)则答案就是

\[\sum_{i=0}^{M+K}3^{M+K-i}\dbinom{N+i-1}{N-1}\sum_{B+C=i}^{B\leq M,C\leq K}\dbinom{i}{B} \]

直接做显然是不行的,考虑优化,这里不要考虑拆组合数,注意到最后的组合数求和的式子一定是对一个区间\([l,r]\)\(\sum {i\choose B}\),且当\(i\)变化至\(i+1\)时,左右端点至多变化\(1\),于是按照杨辉三角的递推式我们可以快速维护后半部分.时间降至\(O((M+K)\log(M+K))\)\(O(M+K)\)

code

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吧.

code

ARC065F

我们将\(l_i\)相同的\(r_i\)\(\max\).之后不难发现对于当前的修改区间\([l,r]\)\(l-1\)及之前的数都是已经确定的.

\(f_{i,j}\)表示\(i-1\)以及之前的都已经确定了,当前(即考虑区间\([l_i,r_i]\)后)还有\(j\)\(1\)可以使用.每次算出新增加的\(1\)的个数后枚举\(i\)位填什么进行转移.

code

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\),那么对每次询问有

\[ans=\sum_{i=l}^r[pre_i\geq l] (i-pre_i)=\sum_{i=1}^r[pre_i\geq l] (i-pre_i) \]

加上时间一维后就是三维,标准的cdq分治

code

posted @ 2019-12-19 00:55  EncodeTalker  阅读(327)  评论(0编辑  收藏  举报