像潮落潮涌,送我奔向自由。|

寂静的海底

园龄:3年2个月粉丝:59关注:15

2022年三月好题收集

收集一些有启发的题目


ABC243F

题意:有一个抽奖,n种奖品,每种奖品出现的概率为wi,求k次抽奖恰好抽到m种不同奖品的概率吗,取模 (n,m,k50)

很容易想到阶段就是目前已经抽的次数和目前抽出的不同礼物数

假设抽到的可重集是S

为了方便计算,我们钦定这个排列的编号是单调递增的,我们只需要求出每种排列,再乘上这种排列的全排列个数。

全排列的个数为

k!cnt1!×cnt2!×cntm!

那么答案就为

k!cnt1!×cnt2!×cntm!×p1cnt1×p2cnt2××pkcntk

发现下边那一坨最后计算不好处理,也不好放进状态里,所以考虑把它的代价放到转移里。

f(i,j,t)表示前j次抽奖(结果均在[1,i])抽出了k 个礼物的概率除以所有次数的阶乘之积。

然后就有转移f(i,j,k)=f(i1,j,k)+t=1jf(i1,jt,k1)×pit /t!

答案即f(n,k,m)×m!

将不好计算的代价处理到造成它的步骤上


解法2 :

考虑f(i,j,k)直接表示前i种奖励,抽了j次,有k个不同的概率。

f(i,j,k)=f(i1,j,k)+t=1jf(i1,jt,k1)×pit×(jt)

其中组合数表示在t次中选择j次(类似插板)

考虑按单增的顺序考虑集合


ABC242F

题意:给出一个n×m的棋盘,求在上面放w个白车,b个黑车,黑白车不能互相攻击的方案数。

(n,m50,w,b2500)

很显然地,每行每列要么只放一种车,要么什么都不放。

枚举哪些行哪些列放黑车,白车,这样黑白车都独立了,

f(i,j,k)表示在i行,j列中放置k个车的方案数(其中每行、每列至少放置一个车)。

ans=i=0nj=0mx=0niy=0mjf(i,j,w)×f(x,y,h)

f(i,j,k)=x=0iy=0j(1)x+yC(ix)(jy)kCixCjy 容斥一下即可(钦定哪些行,列不放)

预处理必要的信息,将子问题独立


CF1648D

题意懒得写。

神仙题 %%%

涉及到区间求和的情况一般都考虑前缀和,又因为只有两次“转弯”,设其位置分别为i,j

ans(i,j)表示在i从1下到2,在j从2下到3的答案,可以求出

ans(i,j)=sum1(1i)+sum2(ij)+sum3(jn)cost

=sum1(i)+sum2(j)sum2(i1)+sum3(n)+sum2(j)sum3(j1)+cost

取出与i,j分别有关项

f(i)=sum1(i)sum2(i1) , g(i)=sum2(j)sum3(j1)

ans(i,j)=f(i)+g(j)+sum3(n)cost(ij)(ij)

不好处理的地方在于走下来,如果没有这个“下来”的过程就比较好处理。

观察接下来将代价拆成两部分:从(1,1)(2,j)的代价以及之后的代价

因为走下来一定需要一条线段,所以我们考虑从哪一条线段走下来的。

从该线段中一点走下来,要么是从之前的某一条线段的末端点走到这个点的,要么是在该线段内第一行走下来的。

dp(j)表示从(1,1)(2,j)的最优的f(i)+cost(ij)

容易发现在这样的枚举下需要用到的只有线段末尾的dp值。

dp(i)=maxrp=i{maxj=lp1rp1{dp(j)},maxj=lprp{f(j)}}

用一个简单的线段树维护min{dp(i1),s(i)}即可。

接下来需要求出选择每一个线段走下来的价值。

要么直接从该线段上方的某一个点走下来,要么从之前的某一个满足rqlp的线段走来,则答案为max[i,j[lprp],ij]{max{dp(i1),f(i)},+g(j)}cost

使用线段树分治维护x(a)+y(b)(ab)的板子维护即可。

将代价转化为具体与什么相关


P4657

题意懒求得写。

考虑起点确定的情况

那么选择路径的代价就是所有点的儿子的代价之和

f(i,j)表示从根节点向点i走,目前丢了j个磁铁的最大价值

显然地:

f(i,j)=max{f(fa,j),f(fa,j1)+sum(i)a(fa)}

其中sum(i)表示点i周围的点的价值之和。

话说这么智障一个dp+随机化能骗80分/kk

考虑不确定起点的情况

像点分治一样,考虑将一条路径拆成(可以为空的)两部分。

令这条路径上的最高点为A

那么拆成uA,Av两部分。

考虑分别计算两部分的代价。

up(i,j,1/0)表示从点i的子树向上走到i的最大价值。

down(i,j,1/0)表示从点i向下走到i的子树的最大价值。

最后一位表示点i是否选择。

发现down 不好转移,会算重,于是参考70分dp做法,钦定只算儿子的代价,最后再加上父亲的代价。

于是有转移

up(i,j,1)=max{(up(son,j1,1),up(son,j1,0)}+sum(i)a(son)

down(i,j,1)=max{(down(son,j1,1),down(son,j1,0)}+sum(i)a(fa)

计算答案和许多此类dp一样,都是在合并儿子时计算。

ans=maxi+jv{ans,max{up(x,i,1),up(x,i,0)}+max{down(son,j,1),down(son,j,0)}}

ans=maxi+jv{ans,max{up(son,i,1),up(son,i,0)}+max{down(x,j,1)+a(fa)a(son),down(x,j,0)}}

加上father是因为x本身的代价是没有计算father

减去son是因为up计算了x本身的代价,然而son是路径上更靠前的节点,故不能提供代价。

类似题目 : P3565

类似点分治,考虑将路径分为两部分考虑,采取“儿子向父亲合并”的办法统计答案


CF1658D2

题意:已知区间[l,r] , 序列{ai}=[l,r],对所有ai异或上x序列变为{bi},给出{bi},[l,r]x.

l,r,x<217

妙题

由于是由原序列异或得来的,所以必存在一个bi=lx (这个性质似乎可以发扬人类智慧)

那么枚举x=bil

考虑对于x,如何快速检查。

由于性质"abaxbx"

所以这些数之间肯定是不同的,所以我们只用考虑(bix)max(bix)min是否恰好对应l,r即可,因为这样ai对应异或回去恰好是[l,r]中的每一个数。

使用Trie即可。

人类智慧法:

由于前面的性质,必然存在一个bi=lx,l+1x,rx

所以x必然是某个bi[l,r]

直接随机取10个[l,r]个数,将他们对{bi}的异或取交集后 brute force即可。


P5760

题意: 维护序列 , 支持以下操作 :

    1.区间加上一个数
    2.查询区间异或和的后m位(二进制下)

n,q105,m10

首先异或和加之间是没有直接性质的(考虑过每一位开一棵线段树,发现不行,因为进位) ,所以难以使用普通的ds维护,因为知道区间异或时整体加是不能 O(1) 地求出的。

对于普通的ds难以维护的题目,考虑分块,却发现分块也卡在了整体打tag的一步上,即无法整体 O(1) 地维护区间异或和随加法的改变量。

由于查询是异或的后10位,于是我们大可不必考虑前面的位,即操作是在模 2m 的意义下进行的 。

那么此时模意义下数的种类就只有 210=1024 种了。

基于元素考虑不现实,考虑基于统计的算法。

有与异或偶数次等于没有异或,所以本质就是查询出现的奇偶性。

加法导致无法按位考虑,所以直接的想法是暴力开1024个桶,统计每个数出现的奇偶性。

然后加就是将桶“旋转”,如下:

假设在模意义下 +x

原本在 0 的值会到达 xk 会到达 (k+x)modn

(我甚至去想了splay)

然后发现由于奇偶性是 bool 的,于是直接使用 bitset<1024> 维护!

具体做法就是开一棵线段树,每一个点存一个 bitset

区间加时若整个区间被包含,则直接打标记,更改这个点的 bitset 的值,使用位运算优化后 “旋转操作如下” :

s = ( (s << d) | (s >> 1024 - d) ) ;

bitset 左移、右移 多出的位会自动补0 , 很好理解。

区间查询相同,在线段树上把大区间分成很多个小区间,将代表着这些区间的 bitset 异或起来即可得到整个区间出现次数的奇偶性,遍历该 bitset 即可。

时间复杂度 :

O((n+q)logn×aw+qa)

其中 a=1024

前半部分是线段树的复杂度计算方式本身复杂度乘上 push_up/down 的复杂度即可。

后半部分是遍历 bitset 的复杂度。

代码较长,放在此处比较占版面,放出关键代码 (线段树) 。

跑的比指令集慢多了


CF1658F

题意: 有一个长为 n 的01序列, 取k个子段 , 使得其长度和为 m ,且这些子段的 0总数/1总数 = 原串的 0总数/1总数 。

构造方案使得kmin 或输出无解。

神仙题,正常人绝对不会往这个方向想。

首先先判无解,当0,1的数量整除 化简后的 n/m 时一定是有解的,因为只选单个的0、1是可行的。

只用考虑1的个数正确( =one/nm )即可。

考虑当n=km 时 , 一定有解k=1

证明:

1\degree k=1 原串即为答案

2\degree k>1

令从i开头长度为m的串的1的个数为ci,即需要找到cx=cnt

那么一定存在p1使得cp1cnt,也存在p2 使得 cp2cnt

证明是反证,若不存在,则c1+cm+1+cnm+1<n

矛盾。

因为|cxcx+1|1

又因介值定理,一定存在一个x使得cx=cnt

nkm 时,再循环意义下重复刚刚的证明2,即将原串复制若干遍,同样存在p1使得cp1cnt,也存在p2 使得 cp2cnt

由于现在在循环意义下,所以 k=12 , 因为有可能是从某个串开头取一段,结尾取一段。


posted @   寂静的海底  阅读(9)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起