2019.11.04【NOIP提高组】模拟 A 组(手动bitset)

这次比赛的T1是原题,但是我还是没有想到。

T1:设f[i]表示第i个障碍为当前路线第一个经过的障碍的方案数,那么我们考虑容斥求f。

考虑用(0,0,0)走到i的总方案数减去经过其他障碍的方案数,那么我们可以枚举经过的第一个障碍j,则f[i]=(0,0,0)到i的方案数-f[j]*j到i的方案数。

最终求答案得方法和上面同理。

总结:对这一类组合dp题,我们经常要指定类似于“第一个”的点,以此达到降维或化简的目的。

T2:我们用一条长度为m,宽度为k的扫描线从上往下扫整个矩阵。设bitset数组s[i][j]表示i这个值当前在j列是否有出现过,g[i][j]表示从(i,j)这个位置往下k位是否有与a[i][j]相同的值。

每次下移的时候,我们先加入第i+k行的数。在加入这些数时,我们求每个j在bitset上的前驱和后继,然后利用前驱和后继判断当前加入的这个数会对那些f产生影响。注意这里有影响的f是一个区间,所以我们用差分。这个很好推。

然后再删除第i行,这时我们要用g来判断一下当前列是否已经没有a[i][j]这个值了。若没有,则从bitset中删去它。此时和上面一样,判断会对那些f产生影响,同样用差分来区间修改。

最后求一遍前缀和就可以了。

注意这里为了求前驱和后继,我们需要打人工bitset。bitset的原理就是把一个有很多位的二进制数每三十二位压一压,这个可以手动实现。在查询的时候我们可以一块一块枚举,这样就节省了很多时间了。

T3:通过找规律发现(然而我不会找)p'[i][j]=(-1)^{i+j}*i^{m}*\binom{i}{j}

当平方之后,我们可以把正负号去掉,然后就变成了ans=\sum (i^{2m}*\binom{i}{j}^{2})

对于每一个i,\sum \binom{i}{j}^{2}=\sum \binom{i}{j}*\binom{i}{i-j}=\binom{2i}{i}-1(1<=j<=i)。

因为在i个中选j个,再在另外的i个中选i-j个,那么就相当于在2i中选i个。因为j>=1,所以要-1。

这样就可以O(nlogm)做了。

总结:关键还是要学学逆矩阵。

发布了149 篇原创文章 · 获赞 24 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chiyankuan/article/details/102906066