10.12 csp-s模拟测试70 木板+打扫卫生+骆驼

Posted jrf123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10.12 csp-s模拟测试70 木板+打扫卫生+骆驼相关的知识,希望对你有一定的参考价值。

T1 木板

求sqrt{n}~n间有多少个数的平方是n的倍数

通过打表可以发现(我没带脑子我看不出来),符合条件的数构成一个等差数列,公差为首项

而首项就是将n质因数分解后每个质因数出现次数除二,向上取整,这个数一定是大于sqrt{n}的最小的符合条件的数

sqrt{n}将n分解质因数后求出首项,(n-1)/首项就是小于n里有几个,即答案

积累:papa大神教我,打表之前先猜规律,用小点看看猜的对不对,然后再用大点验证,想不出来的数学题就打打表,找找规律

 

T2 打扫卫生

首先肯定是dp

考场写的是n^2的,每次用桶把a[j]的贡献减去,更新答案,最后再循环一遍都加回来,T60

但我们发现如果不同的数的个数大于了sqrt{n},那么他一定不优(大于sqrt{n},那还不如一段就一个,这样就只有n)

所以我们可以在往回加的时候特判,如果cnt大于sqrt{n},那就记录下这个位置,然后break,下次循环就只从pos循环就行了,加上这个减枝可以到T80

正解:cnt一定小于sqrt{n},那么我们枚举i前不同的数的个数,复杂度就降到了O(nsqrt{n})

用pre[a[i]]记录a[i]上次出现的位置,b[j]表示从b[j]+1~i一共有j个不同的数,c[j]表示从b[j]+1~i有多少个不同的数

i++后,如果pre[a[i]]<=j,说明a[i]在b[j]+1~i-1这一段没有出现过,所以b[j]+1~i这一段中不同数的个数就变成了c[j]+1,更新c[j],同时更新f[i]数组

如果c[j]>j,我们为了维护c[j]==j,就需要调整b[j]的位置,使b[j]合法

设pos=b[j]+1(原位置),如果pre[a[pos]]>pos说明在后面还有一个a[pos],那么删掉这个对个数没有影响,直到pre[a[pos]]<=pos,那么删掉这个数,pos+1~i这个区间就正好有j个数了,更新b[j]=pos,c[j]=j

 

以上是关于10.12 csp-s模拟测试70 木板+打扫卫生+骆驼的主要内容,如果未能解决你的问题,请参考以下文章

「10.12」木板(数学)·打扫卫生(神仙DP)

csp-s模拟测试70

[考试反思]1012csp-s模拟测试70:盘旋

[考试反思]1026csp-s模拟测试89:不公

0929CSP-S模拟测试赛后总结

[考试反思]1006csp-s模拟测试61:休止