7月做题记录
7月做题记录
P6837 [IOI 2020] 数蘑菇
如果发现询问多个没太多性质,那么正解多半是询问少数几个,所以多考虑询问某些特定较小数量时的性质
首先\(O(N)\)的就是每个都和\(0\)问一遍
然后\(O(\frac N2)\)的,考虑可以放成A?A?,然后俩问号都能确定
然后进一步,感觉到大致是\(O(\sqrt N)\)级别的,根据\(O(\frac N2)\)的提示,可以先确定\(\sqrt N\)个A/B的位置,然后剩下的根号个根号个一组一起问,显然可以知道问的点里A/B的数量,具体每个点是啥不一定确定,也没必要
然后现在就是考虑优化,发现主要是找到\(\sqrt N\)个A/B这里,需要花费\(2\sqrt N\)的步数,考虑优化
同样参考\(O(\frac N2)\)的做法,可以优化到\(\sqrt N\)步
但还差点,现在我们是能一步确定俩,考虑能不能更多
显然一步能确定的已经到上限了,考虑两步能不能确定五个,设分别为\(x\)、\(y\)、\(z\)、\(u\)、\(v\)
第一步:AxAyAz
\(z\)一定能确定,\(x\)、\(y\)要么能确定,要么能知道\(x\neq y\),如果\(x\neq y\)的话,考虑询问BxBAyAuAz就可以确定了
P6836 [IOI 2020] 装饼干
首先找到check一个\(\{y_i\}\)是否合法的方法:
显然考虑数位\(dp\),要么从低位往高位\(dp\),要么从高往低位\(dp\),显然这里注意到从高往低位好表达限制一点
\(dp[i][j]\)表示已经考虑了\(>i\)的位,对于\(0\sim i\)位的限制是\(j\)
转移考虑\(y_i\)是否取\(1\)
- \(y_i=0\),此时从\(dp[i-1][j]\)转移来
- \(y_i=1\),从\(dp[i-1][j-2^i]\)转移来,且此时显然要有\(j\geq 2^i\)
然后可以发现,若\(j\geq 2^i\),对第一个转移,可以直接预处理出\(dp[i][lim[i]]\)(\(lim[i]\)就是初始关于\(a\)的那个限制),然后直接用这个值就行
所以实际上递归的时候只会至多往下递归一次,即单次复杂度\(O(K)\),然后需要算所有\(dp[i][lim[i]]\),所以总复杂度\(O(QK^2)\)
P6829 [IOI 2020] 植物比较
首先你考虑能不能找到一个合法的\(\{h_i\}\)
考虑按\(h\)的值从大到小确定,显然当前最大值的位置\(x\)在环上一定有:\(r_x=0\),且\(x\)前\(k-1\)个要么已经有值了,要么\(r\)不等于\(0\)
显然当\(k>\frac n2\)时这个\(\{h_i\}\)是可以唯一确定的
考虑\(k\leq \frac n2\)时,如果某一时刻有多个\(x\)满足要求,怎么办
手玩可以发现,似乎不管选哪个\(x\)都不会导致最后无解,考虑这是为啥
这里就要考虑到我们求出的\(\{h_i\}\),本质上只需要任意相邻\(k\)个满足\(r\)的要求,而你手模一下可以发现,任意相邻\(k\)个的赋值时的先后顺序一定是固定的,所以说无论选哪个\(x\)都行
那么现在只需要用求出的这个\(\{h_i\}\)得到任意相邻\(k\)个间的大小关系,然后建\(DAG\),就可以得到原问题的答案了
但要直接建肯定复杂度爆了,考虑简化一下,显然只需要建边\(x\)和\(x\)前/后\(k-1\)个中,\(<h_x\)且最大的那个点
然后考虑check是否有\(h_x\)一定大于\(h_y\)
显然贪心的跳就是从\(x\)一直往左/右跳,直到下一位超过\(y\)或值小于\(h_y\),然后看当前\(x'\)和\(y\)的距离是否\(\leq k\)即可
复杂度\(O((N+Q)logN)\)
P7045 「MCOI-03」金牌
做法1
首先,无解的情况当且仅当存在一种牌的数量\(>\lceil\frac n2\rceil\)
这个东西显然可以用摩尔投票判,但是发现摩尔投票的过程实际上就是\(O(2(n-1))\)的了(当然在当前投票的数量为\(0\)时可以省下一个询问)
但是这个check似乎无法避免,考虑能不能就用摩尔投票过程得到的信息组合一下
首先通过摩尔投票的过程,可以把整个序列划分成许多区间,每个区间内的点在进行摩尔投票时,对应正在被投的那个颜色都要相同
发现除了最后一个区间,前面每个区间内,正在被投的颜色的数量会恰好是该区间长度的\(\frac 12\),所以显然此时可以考虑该颜色中间间隔区间内非该颜色的点的方法
而对于最后一个区间,因为显然我们摩尔投票投出来的值一定是最后这个区间的投票颜色,所以显然我们可以取出一些该颜色的点,使得剩下的区间长度的\(\frac 12\)恰好是该颜色在该区间的剩余数量
然后考虑把这些区间拼起来,因为在第一轮询问时,区间与区间之间那次询问可以省略,所以这里在把区间\(y\)拼到区间\(x\)后面时,问一下\(y\)的第一个和\(x\)的最后一个是否相同,不同就不管,相同就把\(y\)给\(reverse\)一下即可
然后现在还剩下一点投票出的颜色,直接枚热泵举所有满足左右两侧的点都不是该颜色的空隙,显然是可以放下的
严谨证明就是,考虑该颜色已经放了\(A\)个,还剩\(B\)个,那么首先肯定有\(2\times(A+B)\leq n+1\)
然后考虑现在还剩的合法空隙的最小数量是\(n-B+1-2A\),显然有\(n-B+1-2A\geq B\),证毕
询问就是\(2(N-1)\)的了
做法2
还有种流程更简单的方法,考虑现在有一个答案序列,以及维护一个\(sz\),表示当前有\(sz\)个不在答案里且值等于该答案序列末尾的点
然后放入一个点的时候,如果它和序列末尾的值不同,那么把它放上去,如果此时\(sz>1\),则再放一个上去,然后\(--sz\)
最后会剩一些\(sz\),然后和上面那个做法最后的证明一样,只要合法,就一定有足够的空位来放,否则就不合法
询问\(2(N-1)\)
CF618G Combining Slimes
首先考虑算出长度为\(i\)的序列中,出现过\(j\)的概率\(c_{i,j}\)
转移有\(c_{i,j}=c_{i,j-1}\times c_{i-1,j-1}\)
发现当\(j\geq 50\)时,大致这个概率就是\((1-1e-9)^{50}\)接近\(0\)了,所以我们只用管\(j\leq 50\)的值
然后设只出现过一次\(j\)的概率为\(C_{i,j}\),那么\(C_{i,j}=c_{i,j}\times(1-c_{i-1,j})\)
然后考虑\(f[i][j]\)表示长度为\(i\)的序列,钦定当前第一位是\(j\)时的期望和是多少,转移有\(f[i][j]=j+\frac{\sum_{k<j}f[i-1][k]\times C_{i-1,k}}{\sum_{k<j}C_{i-1,k}}\)
对于\(j\)为\(1\)时的\(f[i][j]\)的转移比较特别,考虑到只需要满足它后面一个假如进来的是\(2\)即可,定义新的\(c'_{i,j}\)和\(C'_{i,j}\),表示在要求第一个操作的一定是\(2\)下的概率
转移类似,\(f[i][j]=j+\frac{\sum_{k>j}f[i-1][k]\times C'_{i-1,k}}{\sum_{k>j}C'_{i-1,k}}\)
答案就是\(\sum_k f[n][k]\times C_{n.k}\)
对于\(i\)、\(j\)小于等于\(50\)的,直接算,大于的可以用矩阵做
复杂度\(O(50^3logN)\)
还有种做法大概是,考虑用\(1\)把原序列划分开,然后除第一个序列外,每个序列的开头都得是以\(2\)操作为开头的,然后又发现\(2\)操作除了最后那一次,其余时候都能直接表示为\(1+1\),即俩\(1\)操作,或者说把俩连续的\(1\)操作看做一个\(2\)操作
注意到数\(x\)在不考虑第一个必须是\(2\)时拼出来的概率是\(\sum_{i=0}^{2^{x-2}} C_{2^{x-2}}^ip^{2i}(1-p)^{2^{x-2}-i}\)即\((p^2+1-p)^{2x-2}\)
总之前\(n-50\)个矩阵转移,后面的手动转移
复杂度\(O(50^3logN)\)
CF605E Intergalaxy Trips
设\(dp[x]\)表示从\(x\)走到\(n\)的期望步数
若我们已知所有的\(dp\)值,考虑\(dp[x]\)怎么转移的
考虑当前时刻\(x\)可以走出去的边的存在情况,如果存在能走到一个点\(y\)满足\(dp[y]<dp[x]\),显然会走这个\(y\),且会走\(dp\)最小的那个,否则不存在时则一定走回\(x\)
设\(f(x)=\prod_{dp[y]<dp[x]} (1-p[y])\),则\(dp[x]=\frac{1+\sum_{dp[y]<dp[x]} dp[y]\times g(x,y)}{1-f(x)}\),这个\(g(x,y)\)就是算的\(x\)目前所有联通的点里\(dp\)值最小就取到\(dp[y]\)时的概率
转移显然是个DAG,初始把所有未知的\(dp[x]\)设为\(inf\),考虑类似dij的过程,用已经确定的那些\(dp\)去更新未确定的,每次都会至少确认一个新的\(dp[x]\)
总复杂度\(O(N^2)\)
P5516 [MtOI2019] 小铃的烦恼
首先看眼数据范围,发现\(p_{a,b}=1\),所以这个失败概率就是没有的
那么现在最终是那种颜色,显然它的概率、期望之类的只和它初始有多少个有关
所以算\(f[i]\)表示初始有\(i\)个当前颜色,求最终颜色就是该颜色的期望步数
转移有\(f[i]=\frac{i(n-i)}{n(n-1)}f[i+1]+\frac{i(n-i)}{n(n-1)}f[i-1]+\frac{n(n-1)-2i(n-i)}{n(n-1)}f[i]+w_i\),其中\(w_i\)表示初始有\(i\)个当前颜色,最终颜色就是该颜色的概率
\(w[i]\)的转移类似,\(w[i]=\frac{i(n-i)}{n(n-1)}w[i+1]+\frac{i(n-i)}{n(n-1)}w[i-1]+\frac{n(n-1)-2i(n-i)}{n(n-1)}w[i]\),写成递推的形式\(w[i+1]=2w[i]-w[i-1]\),即\(w[i+1]-w[i]=w[i]-w[i-1]\),因为\(w[0]=0\),\(w[n]=1\),所以\(w[i]=\frac in\)
现在考虑\(f\)的转移,有\(f[i+1]=2f[i]-f[i-1]-\frac{n-1}{n-i}\),\(f[0]=0\),\(f[n]=0\),现在想要推出\(f[1]\)的值
参考上面\(w[i]\)的过程,这里可以得到\(f[i+1]-f[i]=f[i]-f[i-1]-\frac{n-1}{n-i}\),那么设\(f[1]-f[0]=f[1]\),则\(f[j+1]-f[j]=f[1]-\sum_{i=1}^j\frac{n-1}{n-i}\)
可以推出\(f[n]-f[0]=f[1]\times n-(n-1)\times(n-1)\),即得到\(f[1]=\frac{(n-1)^2}n\)
然后递推即可,复杂度\(O(N^2)\)
当然我们求出\(f\)的递推式后,可以高斯消元,注意到第\(i\)行只需要去把\(i+1\)行上的\(i\)位给消了就行,顺便把自己的\(i+1\)位给消了
复杂度\(O(N^2+N)\),这个\(O(N^2)\)是输入的复杂度,后面才是真正解决问题用的复杂度

/zy
浙公网安备 33010602011771号