竞赛讨论区 > 【题解】牛客练习赛22
头像
牛客网小运营
发布于 2018-12-27 17:58
+ 关注

【题解】牛客练习赛22

(题解由比赛出题人提供,点击右侧“本文相关内容”的题目即可开始做题)

T1 有趣的题
模拟即可

T2 送分题
模拟即可

T3 简单瞎搞题
考虑DP,f[i][j]表示前i个数,和为j,是否可行
假设都同阶
每次转移的复杂度O( n )
第一维O( n )
第二维O( n^3 )
总复杂度O( n^5 )
然后发现可以用bitset优化转移
总复杂度O( n^5/w ),可以通过

T4 爆搜题
因为数据量很小,所以每次爆搜所有情况,然后按照题意模拟来判断牌的大小即可
我写的复杂度
O(67!52*52)
这里复杂度写的不严谨,请不要在意。

T5 简单数据结构1
先线性筛phi然后考虑用拓展欧拉定理降幂
图片说明
我们发现对一个数取欧拉函数,log次就会变成1,而任何数模1肯定=0,所以就可以算出来了。
然而这么做还会有一些小问题。
首先我们发现后面的phi[p]这一项是可能不会加的
这个怎么办呢?
因为这个不断地幂次增长速度极快,很少几项就能够增长到远大于模数的地步
图片说明
那就先暴力的处理前面几项,然后再正常做,这样就减少了讨论次数
然后加点特判即可
总复杂度O( p + mlognlog*(v) )

T6 简单数据结构2
第四分块
考虑根号分治
定义一个值x出现次数为size[x]
如果没有修改操作,则预处理所有size大于sqrtn的值到所有其他值的答案,以及每个值出现位置的一个排序后的数组
查询的时候如果x和y中有一个是size大于sqrtn的,则可以直接查询预处理的信息,否则进行归并
O( nsqrtn + msqrtn )
有修改操作即在这个做法上改良,因为发现这个做法的根号平衡并没有卡满,所以有改良余地
假设把所有x变成y
由于可以用一些技巧使得x变成y等价于y变成x,所以不妨设size[x] < size[y]
定义size大于sqrtn为大,size小于等于sqrtn为小
定义ans[x][y]为x到y去除附属集合的部分的答案(附属集合是什么下面有说)
x取遍所有值,y只有所有大的值,总O( sqrtn )个
修改:
如果x和y均为大,则可以暴力重构,O( n )处理出y这个值对每个其他值的答案,因为这样的重构最多进行O( sqrtn )次,所以这部分复杂度为O( nsqrtn )
如果x和y均为小,则可以直接归并两个值的位置的排序后的数组,单次O( sqrtn ),所以这部分复杂度为O( msqrtn )
如果x为小,y为大,发现小合并进大的均摊位置数为O( n ),对这个再次进行根号平衡
对于每个大,维护一个附属的位置集合,这个位置集合的大小不超过sqrtn
每次把小的x合并入大的y的时候,即合并入这个附属集合,并且用x到所有大的值的答案更新y到所有大的值的答案,这样
如果合并后附属集合大小超过sqrtn,则O( n )重构y到所有值的答案,这个过程最多进行O( sqrtn )次,均摊复杂度O( nsqrtn )
由于大的值个数 <= sqrtn , 附属集合大小 <= sqrtn,这一部分是单次O( sqrtn )的,所以这部分复杂度为O( msqrtn )
查询:
如果x和y均为大,则在维护的答案中查询min( ans[x][y] , ans[y][x] ),然后将x的附属集合和y的附属集合进行归并,这一部分是单次O( sqrtn )的,所以这部分复杂度为O( msqrtn )
如果x和y均为小,则进行一次归并即可,所以这部分复杂度为O( msqrtn )
如果x为小,y为大,则在维护的答案中查询ans[x][y],然后将x和y的附属集合进行归并,这一部分是单次O( sqrtn )的,所以这部分复杂度为O( msqrtn )
总复杂度O( nsqrtn + msqrtn )
由于维护了所有可能的贡献,而且更新是取min,正确性也得到了保障

其他疑问可加以下交流群(加入一个即可啦~)
牛客多校算法训练营1:453799454
牛客全国算法训练营2:330766563
牛客多校算法训练营3:934889305

全部评论

(0) 回帖
加载中...
话题 回帖

等你来战

查看全部

热门推荐