2023.12.19 近期练习

CF1835C

先前缀和,找 \([x,y]\)\([l,r]\),使得 \(s_{x-1}\otimes s_y\otimes s_{l-1}\otimes s_r=0\)
因为 \(s_{x-1},s_y,s_{l-1},s_r\) 可以随意交换,如果我们找到了两个区间,我们只需要把相交的部分去掉即可。
所以我们可以随意找两个区间使得他们值相等即可。
发现如果有 \(4\) 个数要确定是很困难的。
但是通过观察数据范围得出,序列的长度的平方恰好是值域的大小,这启示我们用根号算法。
考虑生日悖论,我们每次随机一个区间出来,然后存进 map 里面。
只需要随机 \(\sqrt{4^k}=2^k=n\) 次,所以复杂度为 \(O(n)\)
注意当序列长度小的时候,效率会下降,所以直接枚举就行了。
这种问题看似不可做,应多考虑随机算法。

CF1824C

答案有上限:只需要把每个叶子都修改了即可。
如果能修改一个点,使得多个叶子节点不再需要被修改,那么就赚到了。
考虑从叶子节点往上考虑,如果对于节点 \(u\),其两个儿子 \(a_{v1}=a_{v2}\)
那么就可以修改 \(a_u\),同时,我们可以把 \(a_u\) 看做是叶子节点继续计算。
具体操作的话,设当前处理到 \(u\),维护其子树下还剩的叶子节点的值的个数,用 map 即可。
\(a_u\) 修改为其中出现最多的数,如果赚的话。
如果出现次数最多的不止一个呢?那么把多个都放进 map 里面,并把个数设为 \(1\)
最后特判根节点。
这种问题应考虑划分树为子任务去解答。

CF1823E

每个点的度数都为 \(2\),那么可以确定原图是若干个环。
我们不禁想到 SG 函数。考虑如何描述状态。
一个环首先需要先变成链。直接枚举删了几个点即可。
对于长度为 \(i\) 链来说,会分成两部分 \(x,y\),使得 \(i-(x+y)\in [l,r]\)
\(SG_i\) 表示长度为 \(i\) 的链的 \(SG\) 函数。
那么 \(SG_{i}=\text{mex}(f_j)\),其中 \(j\in [i-r,i-l]\),且 \(f_j=\text{mex}(SG_k \otimes SG_{j-k})\)
怎么看都是 \(O(n^2)\) 的。
通过题解启发,已经没有优化的算法,通过打表,发现
长度为 \(n(n<l+r)\) 的环的 \(SG\) 函数是 \(n/l\)\(n\ge l+r\) 的是 \(0\)
这种问题看似不可做,应考虑找规律,打表。

CF1806D

考虑拆贡献。如果 \(i\) 能做贡献,即 \(i\) 直接连向 \(1\),考虑其条件。
首先不可能是在 \(i\)\(i+1\) 直接连边而导致连向 \(1\) 的,因为 \(i+1\) 只能连向 \(i+2\),不可能到 \(1\)
所以 \(i\) 做贡献在于 \(i-1\)
只需要满足 \(a_{i-1}=0\),其次 \(i-1\) 的根需要是 \(1\) ,且 \(i-1\) 是前 \(i-1\) 个数的最后一个即可。
\(i-1\) 是前 \(i-1\) 个数的最后一个的概率是 \(\dfrac{1}{i-1}\)
\(i-1\) 的根需要是 \(1\) 的条件是什么呢?即 \(1\sim {i-1}\) 成为一个连通块。
那么对于 \(a_j=1\)\(j\) 需满足 \(j+1\) 需已经联通 \(1\),转化为 \(j\) 不能是最后一个,概率是 \(\dfrac{j-1}{j}\)
把概率乘起来,把贡献加起来即可。
这种问题需要考虑拆贡献的方法,并且寻找充要条件去转化并求解。

CF1821F

建议先想朴素的 dp。
\(f_{i,j,0/1}\) 表示已经放 \(j\) 棵树,上一棵树放到 \(j\),是向左/向右。感觉没什么用。
考虑排列组合。
如果已经确定了放 \(m\) 棵树的区间,那么树的放法是 \(2^m\)
\(m\) 个区间的方案数是多少呢?是 \(C(n-mk,m)\),即把 \(n-mk\) 个数插了 \(m\) 个板。
看似总的答案是 \(2^m\times C(n-mk,m)\),然而显然是有重复的。
考虑容斥,首先减去一棵树在同一个位置,然而被计算了两次的方案数。
即有两种区间覆盖方式,但是端点有一处重合,这棵树就放在这。
这里要减去的方案数是 \(C(m,1)\times 2^{m-1} \times C(n-(m+1)k,m)\)
继续容斥,答案是 \(\sum_{i=0} C(m,i)\times (-1)^i \times 2^{m-i}\times C(n-(m+i)k,m)\)
这种问题考察了容斥原理的使用,是经典的容斥。

CF1863F

我们可以列出一个简单的 dp。设 \(f_{i,j}\) 表示 \([i,j]\) 可否到达。初始 \(f_{1,n}=1\);
\(s(l,r)\) 表示 \([l,r]\) 的异或和。若 \(s(i,k)\ge s(k+1,j)\),那么 \(f_{i,k}=f_{i,j}\)。令一边同理。
然而这样做复杂度为 \(O(n^3)\)。故考虑异或的性质:
\(s(i,k)\ge s(k+1,j)\),由于 \(s(i,k)\otimes s(k+1,j)=s(i,j)\)
\(s(i,j)\) 最高位是 \(x\),那么 \(s(i,k)\)\(x\) 位势必是 \(1\)。因为第 \(x\) 位一定是从高到低第一个不相同的位置。
所以对于 \([i,k]\),假设从 \([i,j]\) 转移过来,那么只需存在 \(j\) \(\in[k+1,n]\),使 \(highbit(s(i,j))\in s(i,k)\) 即可。
这种问题首先得找充要条件,然后要想到二进制中的拆位。

CF1809F

显然是优先加 \(1\) 价的油直到加满,如果不够了再加 \(2\) 价的油。
所以每个 \(1\) 价的点都是必要加油的。我们把路径上相邻的 \(1\) 拎出来,设距离为 \(s\)
我们钦定一段路径末端把油开完,方便计算。
\(s\le k\),那么这段代价是 \(s\),否则只能在路上加油,代价为 \(k+2(s-k)=2s-k\)
两端的代价也是同理计算的。
我们只要通过倍增预处理或双指针就可以了。
这种问题要采用隔离分析,每段都是独立的。

posted @ 2023-12-19 19:52  s1monG  阅读(32)  评论(0)    收藏  举报