码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-10-12 22:57:29      阅读:102      评论:0      收藏:0      [点我收藏+]

标签:pap   记录   break   循环   需要   模拟   枚举   质因数   有一个   

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(n\sqrt{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 木板+打扫卫生+骆驼

标签:pap   记录   break   循环   需要   模拟   枚举   质因数   有一个   

原文地址:https://www.cnblogs.com/jrf123/p/11664119.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!