2019集训队作业做题实况[3](61-66):

24-2(计数)(19.12.29):

https://atcoder.jp/contests/agc035/tasks/agc035_f

https://atcoder.jp/contests/agc035/submissions/9203617

对于行i和列j,只有k[i]=j,l[j]=i-1,或k[i]=j-1,l[j]=i会重复。

所以容斥枚举一共有多少对行列是这样重复的即可:

\(Ans=\sum_{k=0}^{min(n,m)}C_n^k*C_m^k*k!*(n+1)^{m-k}*(m+1)^{n-k}*(-1)^k\)

42-1(匹配+构造)(20.2.1):

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

https://codeforces.com/contest/547/submission/69965423

方法1:

首先这是一个二分图,原来的点就是二分图上的边。

如果所有点的度数都是偶数,可以跑若干次欧拉回路。

回路上的边交替染色即可。

一个点是奇数的话,就随便断它的一条边。

之后接回去的时候看看颜色即可,这样显然差不超过1.

方法2:
点还是点。

对于x相同的,若有k个,则连k/2条边,边连接的点互不相同,k奇数的话剩下一个不用管。

y相同的同理。

这样染色,使每条边的两个点的颜色不同即可。

可以证明不会有冲突(奇环),因为走的边一定是x轴和y轴的边交替走,想要回来一定要走偶数条边。

45-1(计数+树形dp)(20.2.6):

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

https://codeforces.com/contest/512/submission/70426270

先考虑哪些点是不合法的:
1.边双里的点

2.边双之间的路径上的点

找到这些点可以通过直接Turpo找。

那么剩下的点显然是个森林,我们把树分成两种:
1.有根树,即这棵树有一个点和不合法的点有连边(不可能有两个这样的点),那么这个点一定是这个树最晚取走的点,以它做根,对于每个子树同样满足这个性质,所以树形dp设\(f[i][j]\)表示i为根的子树里选了j个点的方案数。

转移显然,主要i一定是最后一个点,所以\(f[i][siz[i]]=f[i][siz[i]-1]\)

2.无根树, 就是没有那样的点的树。这个枚举每一个点做根,做那样的dp,把所有结果加起来,注意对每一个大小为x的子树,会被不属于这个子树的点作根时统计到一遍,所以除以(siz-x),当x=siz时不用除以。

复杂度由树形背包可得是\(O(n^3)\)

39-1(推理讨论+ecgcd+最短路)(20.2.6)

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

https://codeforces.com/contest/516/submission/46652574

杂题分享时淘过的,随便丢一篇题解:
https://blog.csdn.net/jokerwyt/article/details/103021688

12-3(动态规划+NTT)(20.2.7):

https://atcoder.jp/contests/agc021/tasks/agc021_f

https://atcoder.jp/contests/agc021/submissions/9937374

\(f[i][j]\)表示i行j列,其中i行一定不为空的方案数。

考虑新加一列,有k行在前j列的没有染色,在新加的这列有了染色。

当k=0时,只用考虑原来的j行对这一列的最小最大行影响:

\(f[i][j+1]+=f[i][j]*(1+i+C(i,2))\)

否则,考虑把k行插入原来的j行中,但是新的列的最大最小行还可能是原来的j行,分2*2=4种情况(即上下是否是原来的)可以得到系数

\(f[i+k][j]+=f[i][j]*((C(i+k,k)+C(i+k,k+1)+C(i+k,k+1)+C(i+k,k+2))=C(i+k+2,k+2))\)

最后\(ans=\sum_{i=0}^nC_{n}^i*f[i][m]\)

第二个转移可以NTT优化,时间复杂度:\(O(nm~log~n)\)

19-2(动态规划+xjb优化)(20.2.17):

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

https://codeforces.com/contest/708/submission/71224703

考虑一行一行的转移,设\(f[i][l][r]\)表示前i行联通,第i行剩[l,r]的概率和。

\(f[i][l][r]=p[l][r]\sum_{[u,v]∩[l,r]≠∅}f[i-1][u][v]\)

\(p[l][r]\)表示一行k轮后剩\([l,r]\)的概率。

\(v[i]\)表示一行的左边搞了i个概率,

\(v[i]=p^i*(1-p)^{k-i}*C_{k}^i\)

\(p[l][r]=v[l-1]*v[m-r]\)

直接做\(O(n^5)\),显然可以前缀和优化。

\(s\)\(f[i-1]\)的二维前缀和,那么:
\(f[i][l][r]=p[l][r]*(s[m][m]-s[l-1][l-1]-s[m-r][m-r])\)

\(-s[m-r][m-r]\)是因为对称性。

发现用到的都是\(s[x][x]\)这样的。

干脆直接维护\(s[x][x]\)吧。

\(g[i][j]=\sum_{x<=j}\sum_{y<=j}f[i][x][y]\)

\(g[i][j]=g[i][j-1]+\sum_{x<=j}f[i][x][j]\)

\(g[i][j]=g[i][j-1]+\sum_{x<=j}p[x][j]*(s[m][m]-s[x-1][x-1]-s[m-j][m-j])\)

\(g[i][j]=g[i][j-1]+\sum_{x<=j}v[x-1]*v[m-j]*(s[m][m]-s[x-1][x-1]-s[m-j][m-j])\)

从小到大枚举j维护两个东西的和就可以了。

posted @ 2019-12-29 16:54  Cold_Chair  阅读(259)  评论(0编辑  收藏  举报