2019集训队作业做题实况[2](31-60):

22-3(19.11.9)(计数):

https://atcoder.jp/contests/arc096/tasks/arc096_c

https://atcoder.jp/contests/arc096/submissions/8343796

mdzz复杂度就多了个\(n\)难受啊。

考虑算\(>=2\)次显然非常地难算。

所以肯定是容斥有多少个不合法的。

于是我就想到枚举\(x,y\)表示至少有\(x\)\(0\)次的,\(y\)\(1\)次的方案数。

容斥系数显然是\((-1)^{x+y}\)

考虑在枚举个\(j\)表示把\(y\)个分到了\(j\)个集合,系数是\(S_{y,j}\)

剩下的东西,自己可以成集合,\(2^{2^{n-x-y}}\)

也可以加入这\(j\)个集合,\((2^{n-x-y})^j\)

得到了\(O(n^3)\)做法,不会优化。

然后发现,\(x,y\)是可以一起枚举的,枚举\(x+y\),系数变成了\(S_{x+y+1,j+1}\),哭了。

34-3(19.11.9)(dp):

https://atcoder.jp/contests/agc026/tasks/agc026_d

https://atcoder.jp/contests/agc026/submissions/8358342

考虑有两个等长相邻的列,已经确定了左边,现在要确定右边。

容易发现,当左边没有任意两个相邻相同时,方案数是2,否则是1。

由此不难思考出一个dp:
\(f[i][j]\)表示前\(i\)列搞完了,第i列的最低相同点在\((H[j-1],H[j]]\)间的方案数(H是h排序去重后的数组)。

讨论一下即可得到方程。

直接做是\(O(n^3*log~n)\),发现可以优化到\(O(n^2)\),懒得改了,所以\(n=100?\)

25-3(19.11.9)(容斥+树上背包):

https://atcoder.jp/contests/arc101/tasks/arc101_c

https://atcoder.jp/contests/arc101/submissions/8370764

直接dp可能有点难搞。

不妨考虑容斥,如果至少有x条边没有被遍历,那么系数是\((-1)^x\)

这x条边会把整棵树割成若干联通块,每个联通块内随便连。

预处理\(g[n]\)表示n个点随便乱连的方案数:
\(g[n]=g[n-2]+g[n-4]*(n-2)*(n-3)\)

那么考虑用树上背包去实现容斥的过程,\(f[i][j]\)表示以i为根子树中,以i为根的联通块有j个点,每次可以转移上面,或者把联通块独立。

9-3(19.11.10)(dp)

https://atcoder.jp/contests/arc101/tasks/arc101_d

https://atcoder.jp/contests/arc101/submissions/me

考虑转换成一个新问题,每个点变为\((c[i],d[i])\)表示向左向右的距离。

一开始在\((0,0)\),每次可以走到\((x+1,y)\)\((x,y+1)\),经过一个时就确定了,问方案数。

也可以看做走这样一条的折线:\(x1<x2<x3…,y1<y2<y3…\),那么直接dp即可。

18-3(19.11.17)(二分):

https://atcoder.jp/contests/agc029/tasks/agc029_c

https://atcoder.jp/contests/agc029/submissions/8503833

二分答案,然后每个串肯定填大于前面字符串的字典序最小的串。

维护每个串选了什么,相同的一段字符缩到一起,然后搞一搞就好了。

27-3(19.11.17)(构造):

https://atcoder.jp/contests/agc028/tasks/agc028_c

https://atcoder.jp/contests/agc028/submissions/8506342

那个\(min(a[x],b[y])\)有点烦人,因为最终答案也是求\(min\),不如改成二选一,这样会变得可做一些。

然后考虑每条边是选左边还是右边。

首先有两种合法的方案:
1.全部选左边。

2.全部选右边。

3.除了1、2的情况,考虑选边交界处,这种情况下显然没有被一条边选的点的个数=被两条边选的点的个数\(>0\)

首先任意选边都有:没有被一条边选的点的个数=被两条边选的点的个数

所以枚举一个被两条边选的点,保证至少选了一个,再从剩下的权值中选n-2个最小的就好了。

39-3(19.11.18)(构造):

https://atcoder.jp/contests/agc027/tasks/agc027_d

https://atcoder.jp/contests/agc027/submissions/8509087

不妨使m=1。

黑白染色,使白的格子是周围四个黑格的lcm+1。

那么如何让所有格子互不相同且四个黑格的lcm较小。

\(x+y\)\(x-y\)来划分,黑格的数是它所在的正对角线和负对角线的质数乘积。

至少需要1000个质数,而白格最多是四个质数的乘积,\(p[1000]^4<10^{15}\)

14-1(19.11.19)(网络流):

https://codeforces.com/contest/611/problem/H

https://codeforces.com/contest/611/submission/65335041

考虑定1为根,则接下来的每条边都要匹配一个点,存在完美匹配是必要条件。

做出一个匹配后,每条边就已经确定了一个点的编号。

另外一个的点其实可以随便确定,只要是个树就好了。

所以直接从1开始bfs,若不能遍历到所有的点也没有解。

15-3 (19.11.20)(构造):

https://atcoder.jp/contests/arc102/tasks/arc102_d

https://atcoder.jp/contests/arc102/submissions/8534636

考虑倒着来,对1,2,3……,n进行交换。

假设交换了x-1,x ,x+1,变成了x+1,x,x-1。

可以得到的结论是x+1不可能再变回右边去,x-1不可能再变会左边去,这很显然。

\(b[i]\)表示i出现p的\(b[i]\)位置,把i->b[i]这一段视为相关连续段,然后不断合并,得到极小相关连续段。

然后维护p[1-?]的min值和max值即可提出每一段相关连续段,设为l,l+1,……,r。

可以发现,对于x=l+1,l+3,……,有p[x]=x。

剩下的位置,互相之间会交换,通过手玩发现,一个点的移动方向是固定的,同一移动方向的点不能有超越的情况。

即,对于所有向右的点(包括不动的),要到的位置随原位置递增而递增。

即,对于所有向左的点(包括不动的),要到的位置随原位置递增而递增。

41-3(19.11.20)(树形dp):

https://atcoder.jp/contests/arc097/tasks/arc097_d

https://atcoder.jp/contests/arc097/submissions/8537365

非常容易的树形dp。

首先如果叶子是黑点删了,因为走进去不会更优。

直到所有叶子都是白点。

若直接从一个起点开始走回来,\(Ans=2*(D-1)+\sum !((r[x]\&1)xor ~color[x])\)

若选一个起点和终点,则这条路径上的点除了终点以外反色,同时还少走len-1个点。

那么随便选一个根,记录f、g分别为子树里选起点、终点能是ans减少的最大值。

每次合并两个子树,同时更新f、g。

30-3(19.11.27)(计数、动态规划):

https://atcoder.jp/contests/arc100/tasks/arc100_d

https://atcoder.jp/contests/arc100/submissions/8672436

正难则反,考虑求不合法的。

当m个里本来就有k的连续段时,不合法的=0。

当这m个不是互不相同时,左右独立,所以做一个dp:

\(f[i][j]\)表示长度为\(i\)了,最长连续段是j的方案数,前后的区别是初值不同,做两次最后统计即可。

转移显然,可以前缀和优化。

当m个互不相同时,比较复杂,这m个是哪些数没有关系,问题转换为:

求长度为n时,合法的染色中,长度为m的连续段的出现次数,答案除以\(k!/(k-m)!\)即可。

依然是转换成不合法,还是之前的dp,多记一个长度为m的连续段的出现次数即可。

46-3(19.11.27)(数学几何结论题):

https://atcoder.jp/contests/agc039/tasks/agc039_d

https://atcoder.jp/contests/agc039/submissions/8674584

不想做,直接抄结论的。

https://blog.csdn.net/qq_39972971/article/details/102314467

37-3(19.11.28)(hash):

https://atcoder.jp/contests/arc099/tasks/arc099_d

https://atcoder.jp/contests/arc099/submissions/8679503

直接hash即可,注意要有逆元。

7-3(19.11.28)(构造):

https://atcoder.jp/contests/arc103/tasks/arc103_b

https://atcoder.jp/contests/arc103/submissions/8680192

首先所有点的x+y的奇偶性必须相同,这是个必要条件。

考虑用二进制构造,发现用\(1,2,4,...,2^x\)就可以搞出\(|x|+|y|<2^x\)的奇点,从大到小每次往曼哈顿距离减小的走即可。

偶数的加个1就好了。

28-2(19.11.28)(图论推理):

https://atcoder.jp/contests/agc032/tasks/agc032_c

https://atcoder.jp/contests/agc032/submissions/8680576

有奇点不行。

有一个度数>4的就显然可以。

全部都<4显然不行。

如果只有一个=4,显然也不行。

如果有>2个=4的,显然可可以。

如果有2个=4的,A能不经过B走回自己就行。

3-1(19.11.28)(几何):

https://codeforces.com/contest/575/problem/E

https://codeforces.com/contest/575/submission/65901303

考虑把有效面积的凸包建出来。

显然一定有三个点组成的圆包含所有的区域,证明通过一个大圆不断缩小刚好卡住。

然后

考虑凸多边形上相邻三个点产生的圆会大一些。

好像是取产生最大半径的三个点一定能包含住其它点,不会证明。

45-2(19.11.30)(分析+可持久化线段树):

https://atcoder.jp/contests/agc028/tasks/agc028_e

https://atcoder.jp/contests/agc028/submissions/8702574

首先肯定是逐位确定每一位是0还是1.

问题在于确定了一些状态后,如何判断是否有解。

考虑有解的话,有一种一定有一边新选的high elements全部是原最大点,因为如果两边都有非原最大点且成为high elements,可以交换把它们都去掉。

假设A选的全是原最大点。

设一共剩q个原最大点,A本来有u1个high elements,B本来有u2个high elements,B新选b个原最大点,B一共增加了c个high elements。

则u1+q-b=u2+c

u1-u2+q=c+b

即从剩下的中选一个递增序列,原最大点权值是2,非原最大点权值是1,分奇偶是权值最大再判判。

反过来假设B选的全是原最大点再做一遍。

41-2(19.11.30)(线段树合并):

https://codeforces.com/contest/671/problem/D

https://codeforces.com/contest/671/submission/66011186

线段树合并裸题,不讲了。

35-2(19.12.1)(几何):

https://codeforces.com/contest/698/problem/D

https://codeforces.com/contest/698/submission/66082529

精度把我搞傻了.jpg

考虑求出共线关系后,只需要7!枚举一个打击顺序,用一个bfs模拟一下打击就好了。

23-3(19.12.1)(sg函数结论题):

https://atcoder.jp/contests/arc091/tasks/arc091_d

https://atcoder.jp/contests/arc091/submissions/8722903

辣鸡结论,辣鸡题解,一个归纳搞定,辣鸡出题人。

\(y|x,f(x,y)=x/y\)

\(f(x,y)=f(x-(x/y+1),y)\)

随便加速一下即可。

45-3(19.12.1)(计数,动态规划):

https://atcoder.jp/contests/agc022/tasks/agc022_f

https://atcoder.jp/contests/agc022/submissions/8750998

对折是2x-y,也就是说每个点的系数都是\(±2^?\)

因为权值差的太大,方案数就是系数的方案数。

考虑A关于B对称,A向B连一条有向边。

成了一棵内向树。

每个点的深度决定了是2的几次方。

正负取决于父亲的正负、儿子的个数、是父亲的第几个儿子。

父亲的正负可以去掉,变成于父亲是否相同。

然后考虑设\(f[i][j]\)表示确定了\(i\)个点,叶子中有\(j\)个的儿子数要是奇数。

枚举下一层的点的个数k,\((k-j)~mod~2=0且k>=j\)

那么一开始有\(x0=(k-j)/2+j\)个系数是0,\(x1=(k-j)/2\)个系数是1.

考虑再枚举下一层的系数是0的点的个数\(u\)

那么儿子数是奇数的点的个数恰好是\(|x0-u|\),注意不能多选2、4、6……来抵消,这样会被重复计数。

时间复杂度:\(O(n^4)\)

1-3(19.12.2)(构造):

https://atcoder.jp/contests/arc103/tasks/arc103_d

https://atcoder.jp/contests/arc103/submissions/8755475

考虑相邻两个点\(x,y\)\(d[y]=d[x]+siz[x]-siz[y]\)

先找到最小的点作为叶子,然后找它的父亲。

那么它的父亲的\(dis\)是知道的,看有没有就好了。

就这样一直扫下去,最后判根(重心)可不可以。

17-1(19.12.2)(最短路+博弈+动态规划):

https://codeforces.com/contest/536/problem/D

https://codeforces.com/contest/536/submission/66158532

跑完最短路后,设\(f[i][j]\),表示A已选了距离前i的,B已选了距离前j的,A现在先手,先手-后手的最大值。

\(g[i][j]\)同理表示B先手。

然后需要预处理很多东西来转移。

11-3(19.12.2)(一维数轴问题):

https://atcoder.jp/contests/agc022/tasks/agc022_d

https://atcoder.jp/contests/agc022/submissions/8765433

对着题解超了一波,我现在都还很迷。

27-1(19.12.3)(贪心):

https://codeforces.com/contest/521/problem/D

https://codeforces.com/contest/521/submission/66205940

考虑顺序一定是赋值->加法->乘法。

赋值只取最大且>a[i]的,看做x-a[i]的加法。

然后加法和乘法可以贪心的搞搞,加法也看做乘法。

最后排序取前m大。

注意要用long double来判断分数的大小。

19-3(19.12.3)(计数dp):

https://atcoder.jp/contests/arc093/tasks/arc093_d

https://atcoder.jp/contests/arc093/submissions/8772591

非常简单的计数题。

考虑把1就固定在1的位置,最后答案乘一个\(2^n\)

然后1的每一个祖先的另一个子树的大小分别为\(2^0,2^1,…,2^{n-1}\)

这些子树里最小的会win出来和1 PK。

我们希望不要翻车,那么容斥有多少个翻车的,然后再分配一下是哪个子树,再从大到小分配一下标号。

用状态dp实现这个过程即可。

10-3(19.12.4)(图论):

https://atcoder.jp/contests/arc092/tasks/arc092_d

https://atcoder.jp/contests/arc092/submissions/8790068

有一条边x->y

考虑x能不走这条边走到y,且y不能走到x,则点双数+1.

x不能不走这条边走到y,且y能走到x,点双数-1.

问题在于判断x能否不经过这个边走到y。

假设x为入点的边,出点分别为:d1,d2,…,d0

不经过y,就一定要经过其它的点。

所以顺着扫一遍,求它们不经过x能走到那些点,再倒着扫一遍即可。

15-2(19.12.14)(暴力):

https://codeforces.com/contest/666/problem/D

https://codeforces.com/contest/666/submission/66811506

枚举每一个点保留哪一维,再枚举谁是哪个角。

二分个答案就变成了一堆区间交问题。

32-3(19.12.21)(推理):

https://atcoder.jp/contests/agc025/tasks/agc025_f

https://atcoder.jp/contests/agc025/submissions/9036598

考虑只有两个(1,1)才会一直加下去,遇到(1,0)或(0,1)时会发生神奇的改变。

低位的(1,1)永远追不上一个高位(1,1)。

所以从高到低考虑,用一个栈记录(0,1)和(1,0)的位置,由于每一次相遇一定可以减少至少一个1,所以时间复杂度是:\(O(n)\)

31-3(19.12.28)(构造):

https://atcoder.jp/contests/agc020/tasks/agc020_d

https://atcoder.jp/contests/agc020/submissions/9185635

答案一定是\(\lceil max(a,b)/(min(a,b)+1)\rceil\)

想了很多贪心发现都不对,不如直接逐位确定:
我们需要保证,尽量填'A',任意时候剩下的\(a0,b0\)都满足上面的条件,且当前连续的A不超过k个。

这样得到一个\(O(n)\)的做法。

接着,考虑一直都是k个a,1个b,直到一个分界点,不能这样了,只能填b了。

那么这个分界点以后一定是:

先把多的b0-a0*k个b排掉。

之后就是1个a,k个b的形式。

posted @ 2019-11-09 15:27  Cold_Chair  阅读(413)  评论(0编辑  收藏  举报