省选模拟(56~60)
省选模拟56
1.取石子游戏
?
首先有个结论是后手必胜当且仅当每堆石子个数异或等于0.
设\(dp[i][j][k]\)表示考虑\(i\)堆时选择了\(j\)堆异或值为\(k\)的方案数.
考虑一个性质,如果把石子升序排序后设当前石子个数的最大二进制位为\(k\),那么最后一维大于\(2^{k+1}-1\)的\(dp\)就是不可能存在的了.
因此复杂度变成了\(O(d\sum a_i)\)
2.路径计数
容斥
求经过\(S,T\)恰好一次,边数为\(D\)的方案数.
容斥经过T的次数,枚举长度为\(D-1\)的01串来表示中间经过的点里哪些钦定是\(T\).
01串长这样:\(S\ 0\ 1\ 1\ 0\ 0\ 1\ 0\ 0\ ... T\)
中间为0的路径需要求出来,把不能经过的点也加入进去,有两种情况\(S,T,S,d\)和\(T,T,S,d\)
表示起点终点不能经过的点和路径长度.
不妨设\(dp[i][j][k][d]\)为上述定义的方案数,则第一种情况直接\(n^3d\ dp\)即可.
考虑第二种情况是一个自环的形式,不妨再次容斥\(S\)的经过次数,然后中间为0的路径就没有限制了可以直接\(dp\).
此时发现01串的作用停留在每两个1直接的距离上,所以可以\(dp[i]\)表示最后一个1在\(i\)时的容斥答案,转移加负号可以起到容斥的作用.
3.方格操作
模拟
1个位置是否需要改变取决于\(row[x]+col[y]\)的奇偶性
交换行列的位置使得权值为01的行列自然分开
此时相当于一个2*2的\(mini\)原图形了
直接模拟就是对的
省选模拟57
1.Max
\(dp\)
观察得到\(m\)很小,所以可以状压它
\(dp[i][j][k]\)表示\(i\)位置权值为\(j\)用了\(k\)集合的操作的概率
用来转移\(f[i][j][k]\)前\(i\)个位置最大值为\(j\)用了\(k\)集合的概率
2.Paint
单调栈+线段树
定睛一看原来题目要求最大的内部没有点的矩形周长
可以发现答案的最小值显然是\(2*(max(r,c)+1)\)
所以可以画图发现,一定会横跨要么\(x\)要么\(y\)的中轴
于是暴力的做法就是枚举上边界枚举下边界对经过的点向中轴取\(min\)取\(max\)
正解的做法是在这个的基础上优化
考虑从下往上枚举上边界
那么宽一定是单调递减的
那么考虑维护一个递增的一个递减的单调栈
维护一个线段树节点权值表示宽度减去下边界的纵坐标
每次新加入点的时候就更新单调栈同时在线段树这个区间里区间加或减它的宽度
3.Decompose
\(ddp\)
省选模拟58
1.带权图
高斯消元
根据第二个条件可以列出\(n\)个等式
建出\(dfs\)树后就会有\(m-n+1\)条返祖边
根据这些组成的环再列\(m-n+1\)个等式
暴力就可以高斯消元了
解释下为什么可以只计算一条返祖边构成的环
因为计算一下发现多条的一定可以被表示出来
然后考虑优化暴力
发现返祖边都可以被树边和常数表示出来
所以只需要对\(n-1\)条树边进行高斯消元
2.网络
LGV定理
写进了知识点
3.修路
主席树+二分
发现原图的树就是最短路\(DAG\)构成的一棵确定的树
发现\(DAG\)上的返祖边是能够使得断掉某些边后仍保证最短路的原因
考虑维护一个最小的它能够到达的祖先节点的深度
\((u,v)\)合法当\(ret[u]<=dep[v]\)
\(ret\)的求法可以通过差分
然后通过树上主席树维护出来一条祖先链的\(ret\)情况
以深度为下标
省选模拟59
1.杨柳
费用流
发现一个性质
同一个点同一时间只能够有一个棋子的限制是没有用的
因为如果我需要通过这个点到达终点
而这个点还有棋子
那么完全可以让这颗棋子移动啊
所以直接上费用流就完了
满流就合法
2.景中人
\(dp\)
考试的时候想错了,以为不交是最优秀的情况
结果就被D了
一个倒\(T\)就给我整懵了
正解设\(dp[i][j][k]\)表示区间\([i,j]\)考虑大于\(k\)的纵坐标的最小代价
然后我不会转移
3.钦点
?
考试的时候想的差不多
但没想到优化就\(GG\)了
考虑优化连边方式
由若干个中间点优化连边
每个点向约数连边
发现这样连出来的图等效
最后只需要找到最大的连通块
找到一个小于等于\(n\)的割点更新答案就行
考虑优化
约数不用枚举全部
只枚举\(p*p\)的形式就行了
还有,要优化空间啊
所以就不用搞\(tarjan\)缩点双了
象征性的求出来割点就行了
\(orz\ skyh\)
省选模拟60
1.摧毁图状树
线段树+堆
考试的时候看错题意了\(GG\)
考虑叶子一定被选
然后就有了一个维护堆,每次选择深度最大的未被选择的点的贪心暴力
复杂度是\(O(k+\frac{n-k}{k})\)
为啥呢?因为假如把所有选择过的点删掉,那么每个连通块都\(>k-1\)
为啥?因为一个选择了一个连通块中间的点的情况我们不需要啊,中间已经被笼罩住了
考虑优化复杂度
后边那个是调和级数的不用优化了
前边的那个需要让它不再枚举叶子
所以每次操作都加入的是那些叶子的\(K\)级祖先
用线段树+\(dfs\)序找到一个点子树被选择过的最小深度
把叶子单独用一棵线段树搞出来就每次不用添加叶子进堆了
2.排列统计
\(dp\)
\(orz\ mikufun\)
3.归并排序
\(BIT\)
有一个性质
假如说点对\((x,y),x<y\)反了
那么最终排列出来的\(x\)一定在\(y\)后面一位
多试几种情况才能发现
所以对于询问\(x\)在\(y\)位置
就是在问有多少种方案使得\(x\)前面有\(y-1\)个数
考虑点对\((x,y),(z,t)\)
\(z<t<x\) 贡献为2
\(z<x<t\) 贡献为1/0
\(x<z<t\) 贡献为0
考虑贡献为\(y-1\)的情况
相当于在一群\(1/0\)选择使得和为\(y-1-sum\)
组合数搞
修改就用树状数组硬上