2021.2 做题记录 part.2

P7073 [CSP-J2020] 表达式

绿题不会简直丢人
考虑建立出一棵表达式树
考虑一个操作,如果是 1|x 或者 0&x,那么结果和 x 无关
所以答案不会变
相应的,如果是 1&x 或者 0|x 的时候,在 x 取反的时候,结果也要取反
所以我们建表达式树的时候把相应不会变的节点标出来
节点里的子树也都不会变

code

P7324 [WC2021] 表达式求值

发现表达式树求表达式的方法比栈好写不知道多少。。。
首先这题要想到的一个东西是对于这种最大最小值的问题
我们是可以二分的。。。
我们二分一个 \(x\),把所有 \(\leq x\) 的变成 1,其他的变成 0
然后再求一下值,如果答案为 1,那么 \(ans\geq x\)

对应到这道题上
我们发现虽然 \(n\) 非常大,但是对于每一位来说,他的 01 序列都只有 \(2^m\) 种不同的可能。
所以我们可以把这 \(2^m\) 种情况都暴力的求出来
考虑 ? 的处理,我们可以不求值,而是每个点维护 \(p[0],p[1]\) 表示答案为 0 和答案为 1 的次数
最后的答案就是 值\(\times\)出现次数

然后我们对于每一列的数排序一下,查询一下答案
恰好为 \(x\) 的次数即 \(\geq x\) 的减去 \(\geq x+1\)

复杂度为 \(\mathcal O(2^m|E|+nm^2)\)
实际上带了一个 4 的常数
所以需要吸氧才能跑过去
不过反正这道题本身就给开了只是洛谷没默认开(

code

AT3957 [AGC023F] 01 on Tree

考虑贪心,显然第一步要把所有能选的 \(0\) 都选了
然后发现不太好搞。
我们考虑两个 01 串的合并
如果 \(x\) 可以放在 \(y\) 的前面,说明

\[one[x]\times zero[y]\leq zero[x]\times one[y] \]

也就是说,对于全局的 \(\dfrac{one[x]}{zero[x]}\) 最小的 \(x\),他肯定需要跟着他父亲选
所以我们每次把全局最小的和他的父亲合并起来
用并查集维护,直到不能再维护
维护最小值因为有删除,写 deletable-heap 莫名其妙写挂了
所以就用了个 set
\(\mathcal O(n\log n\alpha(n))\)

code

P4284 [SHOI2014]概率充电器

发现考虑充电成功的概率不太好考虑
考虑反过来考虑充电不成功的概率
那么显然有

\[E(x)=(1-q[x])\prod_{y,x\to y}(1-e(x,y)+e(x,y)E(y)) \]

发现这个东西是存在互相约束的
但是高斯消元显然复杂度不太对
发现题目中给出的是一棵树
所以我们考虑换根 dp
我们先处理出 \(p(x)\) 表示只考虑 \(x\) 的子树的概率
考虑转移的过程中可能存在的问题
当我们需要求 \(p(x)\) 的时候,相当于此时 \(x\) 一定不选,那么这个时候从他的子节点过来的 \(y\) 就不会和 \(x\) 牵扯上贡献
所以可以直接转移
然后换根的时候,用 \(f(x)\) 表示 \(x\) 不充电的概率设 \(x\) 的父节点为 \(y\),那么有转移

\[f(x)=p(x)(1-e(x,y)+\dfrac{e(x,y)f(y)}{1-e(x,y)+e(x,y)p(x)}) \]

这样转移同样是对的
因为当我们钦定 \(x\) 不选的时候,\(y\) 的答案就不应该有从 \(x\) 过来的部分

\(\mathcal O(n)\)

code

P1232 [NOI2013] 树的计数

首先考虑把 BFS 序变成 \(1,2,3\cdots,n\)
这样有什么好处呢?
我们发现 BFS 序每一层是连续的,所以问题就转化成了给 BFS 序设置断点
无非就是三种情况
\(i,i+1\) 之间必须断,必须不断,有可能断有可能不断
这三种情况对答案的贡献分别是 \(1,0,0.5\)
最后把所有情况加起来即可
考虑这三种情况分别会在什么时候出现
\(y=x+1\),也就是 \(bfn[y]=bfn[x]+1\)
如果 \(dfn[x]<dfn[y]\)
那么 \(y\) 可以作为 \(x\) 的子树,也可以作为 \(x\) 的兄弟,贡献应该为 \(0.5\)
如果 \(dfn[x]>dfn[y]\)
那么这个时候 \(y\) 一定在 \(x\) 的下一层,贡献为 \(1\)

但是这样做会有不完备的地方
考虑 DFS 序的影响
\(dfn[y]=dfn[x]+1\),即 \(x,y\) 为 DFS 序上连续的两个数
那么这个时候再进行讨论
如果 \(x+1>y\),这个时候 \(x\) 一定比 \(y\) 靠后出现,但是深度差不一定,所以对答案无所谓
如果 \(x+1=y\),这个时候 \(x\) 可以是 \(y\) 的父亲也可以是兄弟,无影响
如果 \(x+1<y\),这个时候 \(y\) 一定是 \(x\) 的一个儿子,也就是说在 \([x,y)\) 这一部分的 BFS 序上只能找到一个断点
显然这个区间上一定有一个 \(1\),否则不能保证这一点
所以这个区间我们打上标记,这里面的所有 \(0.5\) 都应该是 \(0\)

最后统计一下答案即可
关于这个做法的充分性的证明不会(
感性理解吧

非常恶心的思维题
\(\mathcal O(n)\)
code

CF494B Obsessive String

其实挺简单的脑抽了没想到。。。记录一下
\(f[i]\) 表示当前的串选在 \(i\) 的方案数
那么 \(i\) 这个选出来的串的左端点一定要在 \(i\) 最近的匹配的串的左端点的左边
考虑枚举这个 \(j\),转移过来的方案数是一个前缀和的形式
所以我们求前缀和的前缀和就可以 \(\mathcal O(1)\) 转移了

\(\mathcal O(n)\)

code

CF427D Match & Catch

首先有线性的广义 SAM 的做法
考虑枚举 \(s1\) 的后缀
接下来问题就转化成了判断这个后缀的前缀在两个串里的出现次数
我们把这几个串拼在一起,做一个 dp 即可,转移方程为 \(f[nxt[i]]+=f[i]\)

\(\mathcal O(n^2)\)

code

P7114 [NOIP2020] 字符串匹配

考虑枚举 \(AB\) 的长度 \(i\)
接下来一个问题是 \(AB\) 会循环几次
我们考虑 \(exkmp\),求出每个位置的 \(z\)
那么长度为 \(i\) 的串重复的次数为

\[\lfloor\dfrac{z[i+1]}{i}\rfloor+1 \]

正确性比较显然
发现这样做计算贡献仍然是 \(\mathcal O(n\ln n)\) 的,不太好搞

我们在每次枚举 \(AB\) 长度的时候统一计算贡献
考虑 \(S=(AB)^kC\)
那么我们发现所有 \(k\) 为奇数的时候 \(f(C)\) 都是相同的
同样 \(k\) 为偶数的时候 \(f(C)\) 也都是相同的
所以可以分组计算贡献
用一个树状数组维护即可

\(\mathcal O(n\log|\Sigma|)\)
code

AGC047C Product Modulo

一上来似乎感觉非常好搞
但是这个模数非常恶心
考虑枚举最后是 \(i\) 的有多少个
发现并不好计算
考虑把乘法变成加法,这样我们就可以 FFT 了
但是显然不能取对数
不妨设 \(g[i]=2^i \bmod p\)
那么显然 \(g[i]\) 是互不相同的
这个时候我们的第 \(x\) 位和第 \(y\) 位乘上的结果就到了 \(x+y\) 位了
这样我们 FFT 搞一下就好了

\(\mathcal O(p\log p)\)

code

posted @ 2021-02-12 20:30  YuukiYumesaki  阅读(87)  评论(0编辑  收藏  举报