jzoj4009 【GDKOI2015】复仇之魂

不想打了,记录一下思路吧 (不保证式子正确,大致思路)
题目可抽象成,一颗从0开始的树,每个点会分出k支(0除外,无限多),分出来的点权值+ak。
当点的权值>给定的一个L时,就不继续往下延伸,这就是一个叶子。

问第x个叶子的权值是多少。

还有一个轮换机制,转换一下就是:从点x伸出的枝,第一个走的点是x+ak,第二次走的是k进制下x的最后一位在[0,k-1]中轮换+1后再+ak的点。最终第一位可以遍历满[0,k-1]
(因为一颗子树下必定是k的倍数+1个点)

不难发现,因为+ak是k进制下第2位在改变,所以第c层的点范围就是[cak,cak+k-1].

设L=c*(ak)+t (0< t< ak)
易看出必定会第c或c+1层停下。下面讨论 t<k t < k 的情况,t>=k的情况只会在c+1层停下,更简单吧。

注意到一个第c-1层的任意一点(c-1)ak+d (0<=d<=ak-1),他的叶子个数可以计算。

由于儿子中第一位是占满的,所以当最后一位是0..t时,可以继续向下延伸,于是有(t+1)*k个叶子。
剩下的(k-t-1)无法继续延伸,是叶子。
最终就有(t+1)*k+(k-t-1)个叶子。第c-1层肯定是满的,于是我们可以算出某一子树的叶子数和。

从0开始,由于同一层点子树中叶子数相同,我们显然可以找出第x个叶子位于第几子树,向那颗子树走去。
当走到第c层时,就要讨论一下第x个叶子在延伸的地方还是不延伸的地方,好像是要分个三四段的。

最终的复杂度就是层数。也就是O(c)
考虑到1≤X, L, A≤100,000,000, 2≤K≤100,000,000
因此c=L/(ak)<=1e8,可以通过本题。

XC: 这就是你不改题的理由?????!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值