CT02Day1,二分与倍增

正题

      今天早上的比赛很简单,半个小时上厕所,半个小时问题面,半个小时AK,半个小时写对拍,半个小时上厕所,一个小时发呆。不要问我为什么上一个小时厕所,肚子难受得不行

      下午评讲早上的题我也在划水,做自己的题,51nod1111,感兴趣的可以去看看,暂时没有什么好思路。

      正片要从晚上开始,我只会说说那些好思路的题,没有一看就知道怎么做的题(至少是我),由于博主暂时还不懂怎么在linux环境下装QQ,所以只能看简略题面。

      51nod1064简化版

      只要求A[N]怎么做?

      可以发现答案可以写成:Ans=x*A[w]+y*A[w+1]的形式,然后当w=2*k时,有Ans=(x+y)*A[k]+yA[k+1],当w=2*k+1时,有Ans=x*A[k]+(x+y)A[k+1],那么就可以循环,x,y用高精度维护即可,至于51nod1064怎么做,后面会写Blog讲解(flag

      未知题目1

      给定一张DAG,边上有一个数字,有些点是特殊点,一个单词从1出发,到某个特殊点上的边权组成,在字典序比较下,Q次询问,第K小的单词是多少。不存在输出-1.N,M,Q 1e5,K 1e18,字符集是1e5,最后单词用类似Hash输出。

      构造一个类似DAG剖分的东西即可。

      建一个反图,就可以知道每一个点到达关键点的方案数,当然如果大于1e18我们可以直接取成1e18+1,不影响答案。

      考虑一次暴力怎么做,根据字典序处理一下儿子方案数的前缀和,二分走到哪个节点,减一减,往后走就可以了,显然这样每次O(n log n),非常满,考虑如何用树剖思想解决问题,对于每一个点,将方案数最大的儿子钦定为重后继,那么我们可以预处理一下,然后在重链上倍增,每跳一个轻后继,当前方案数就会减半,由于一开始总方案数已经被我们看成1e18+1了,所以最多只会跳log次轻儿子,每次跳轻儿子我们就二分一下,跟一次做法类似,那么总的时间复杂度就是两个log。

      未知题目2

      N个人轮流玩一台机器,赢了赚1,输了亏1,机器以M为周期判定玩家输赢,一旦一个人没钱,大家一起离开,求离开时所有人玩的轮数和。

      转化为求每一个人什么时候结束,取min即可。

      考虑到一个人玩T=m/gcd(n,m)次后会回到自己的位置,所以我们可以倍增出第i个人经过2^j轮后的钱数变化sum,和钱数变化的最小值min,最小值可以用自身的最小值和总和加下一步的最小值更新。那么我们求出倍增求出T次后的sum,min,分类讨论即可知道,若在某T次中就满足a_i+min<0,那么便可以倍增出那个恰好0的位置,一个log即可完成。

      tourist的签到题

      交互

      依次猜100个单调递增的数字,每次问x,返回偏大/偏小/相等,相等之后才可以猜下一个数字。

      最多问2600次,数字根据询问动态生成(动态卡你,懂?

      1e9

      想出分段就很好想了,考虑等分x段,那么就会猜x-1+100次判断在那个区间,100log(1e9/x)二分出准确值,x=60时有最小值2559,当然取100时也可以过恰好2598。

      

 

猜你喜欢

转载自blog.csdn.net/Deep_Kevin/article/details/107826033
今日推荐