【题目】NKOJ-4247 老蒋的数列

本文深入探讨了一道涉及数列生成及查询的复杂算法题,通过观察与分析,揭示了数列生成规则及其背后的数学原理,提出了有效的解决方案。
题目大意

有两个数列a,ba,ba,b,定义如下。已知数列aaa有一个性质:对于任意的正整数xxx,存在唯一的整数对(p,q)(p,q)(p,q),满足aq−ap=xa_q-a_p=xaqap=x。现在有nnn个询问,每个询问给出一个正整数xix_ixi,求出与之对应的整数对(pi,qi)(p_i,q_i)(pi,qi)(先输出qiq_iqi,后输出pip_ipi)。

an={nn⩽22an−1n>2, nmod  2=1an−1+bn−1n>2, nmod  2=0bn=mex{∣ai−aj∣∣1⩽i,j⩽n}\begin{aligned} a_n&=\begin{cases} n&n\leqslant 2\\ 2a_{n-1}&\text{$n>2$, $n\mod 2=1$}\\ a_{n-1}+b_{n-1}&\text{$n>2$, $n\mod 2=0$} \end{cases}\\ b_n&=\text{mex}\lbrace\vert a_i-a_j\vert\vert1\leqslant i,j\leqslant n\rbrace \end{aligned}anbn=n2an1an1+bn1n2n>2, nmod2=1n>2, nmod2=0=mex{aiaj1i,jn}

n⩽250000n\leqslant 250000n250000xi⩽109x_i\leqslant 10^9xi109


思路

这是一道非常奇葩的题目。首先暴力打表方便找规律:

nnn12345678
ana_nan124816214251
bnb_nbn124559910
nnn5354555657
ana_nan531141824531141876106228375210622838052124567610
bnb_nbn5253535454

注意到数列aaa的递推式中有an=2an−1a_n=2a_{n-1}an=2an1的部分,这意味着ana_nan增长得特别快,第60项以前就超过了10910^9109。因此确定一个界限NNN,让该界限内ana_nan的值不至于远远超过10910^9109。先暴力计算a,ba,ba,b数列的前NNN项,统计可能出现的aq−apa_q-a_paqap的值,并记下与之对应的数对(p,q)(p,q)(p,q),时间复杂度O(N2)O(N^2)O(N2)

若在刚才的暴力计算中出现了询问的xxx,说明aq,apa_q,a_paq,ap都比较小,直接输出对应的数对作为答案。下面讨论ap,aqa_p,a_qap,aq都特别大(远大于10910^9109)的情况:

  • qqq为偶数时,
    • q−p=1q-p=1qp=1,有aq=ap+bpa_q=a_p+b_paq=ap+bp,即aq−ap=bpa_q-a_p=b_paqap=bp
    • q−p=2q-p=2qp=2,有aq=ap+1+bp+1=2ap+bp+1a_q=a_{p+1}+b_{p+1}=2a_p+b_{p+1}aq=ap+1+bp+1=2ap+bp+1,即aq−ap=ap+bp+1a_q-a_p=a_p+b_{p+1}aqap=ap+bp+1,与x⩽109x\leqslant 10^9x109矛盾,排除。
    • q−p>2q-p>2qp>2aq−apa_q-a_paqap的值只会更大,排除。
  • qqq为奇数时,
    • q−p=1q-p=1qp=1,有aq=2apa_q=2a_paq=2ap,即aq−ap=apa_q-a_p=a_paqap=ap,与x⩽109x\leqslant 10^9x109矛盾,排除。
    • q−p⩾2q-p\geqslant 2qp2,跟qqq为偶数的情况类似,均排除。

经过上述讨论发现,若ap,aqa_p,a_qap,aq特别大,答案(p,q)(p,q)(p,q)一定满足qqq为偶数,bp=xb_p=xbp=x,且q−p=1q-p=1qp=1。于是问题变成了已知bpb_pbp的值,求bpb_pbp的下标ppp。下面观察数列bbb

  • nnn为偶数时,有an=an−1+bn−1a_n=a_{n-1}+b_{n-1}an=an1+bn1。此时集合{∣ai−aj∣∣1⩽i,j⩽n}\lbrace\vert a_i-a_j\vert\vert1\leqslant i,j\leqslant n\rbrace{aiaj1i,jn}中出现了∣an−an−1∣=bn−1\vert a_n-a_{n-1}\vert=b_{n-1}anan1=bn1,因此一定有bn>bn−1b_n>b_{n-1}bn>bn1
  • nnn为奇数时,有an=2an−1a_n=2a_{n-1}an=2an1。此时集合{∣ai−aj∣∣1⩽i,j⩽n}\lbrace\vert a_i-a_j\vert\vert1\leqslant i,j\leqslant n\rbrace{aiaj1i,jn}中新添加的最小元素为an−an−1=an−1a_n-a_{n-1}=a_{n-1}anan1=an1,而该元素比原来集合中的最大元素an−1−an−2a_{n-1}-a_{n-2}an1an2还要大得多,因此该集合的mex\text{mex}mex值不变,即bn=bn−1b_n=b_{n-1}bn=bn1

所以bbb数列靠后的项都是相邻两项相同,但大多数时候每次增加111,有的时候增加的值超过111。后者发生在nnn为偶数时,集合中出现了bn−1b_{n-1}bn1,但集合中可能原来就有bn−1+1b_{n-1}+1bn1+1。这个bn−1+1b_{n-1}+1bn1+1在添加进集合的时候一定是远大于当时集合中的最大元素的(否则bn−1b_{n-1}bn1早就应该出现),也就是说bn−1+1b_{n-1}+1bn1+1是在之前nnn为某个奇数时添加的。而由上文可知,此时添加的bn−1+1b_{n-1}+1bn1+1就是数列aaa中的某一项。又因为bn−1+1<bn⩽109b_{n-1}+1<b_n\leqslant 10^9bn1+1<bn109,所以数列aaa中的这一项是包含在最开始暴力计算的前NNN项当中的。

鉴于bbb数列在第偶数项会发生变化,将NNN设为奇数。假设bbb数组靠后的项每次增加111,有bp=bN+p−N2b_p=b_N+\frac{p-N}2bp=bN+2pN。但在数列aaa的前NNN项中可能已经出现了(bN,bp)(b_N,b_p)(bN,bp)内的值,每一个这样的值都会导致bbb数列在某一项多增加111。二分查找求出这样的值的个数cntcntcnt,于是

bp=bN+p−N2+cntb_p=b_N+\frac{p-N}2+cntbp=bN+2pN+cnt

bp=xb_p=xbp=x代入,解得

p=2⋅(x−bN−cnt)+Np=2\cdot(x-b_N-cnt)+Np=2(xbNcnt)+N

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值