Codeforces 1981B Turtle and an Infinite Sequence 题解

题目传送门:

洛谷

Codeforces

分析

这道题不难,主要是考思维

首先,或运算有一个性质:

a   ∣   a   =   a a\ |\ a\ =\ a a  a = a

所以,数列和 m m m的关系如下

m m m a 0 a_0 a0 a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3
0 0 0 a 0 a_0 a0 a 1 a_1 a1 a 2 a_2 a2 a 3 a_3 a3
1 1 1 a 0 ∣ a 1 a_0|a_1 a0a1 a 0 ∣ a 1 ∣ a 2 a_0|a_1|a_2 a0a1a2 a 1 ∣ a 2 ∣ a 3 a_1|a_2|a_3 a1a2a3 a 2 ∣ a 3 ∣ a 4 a_2|a_3|a_4 a2a3a4
2 2 2 a 0 ∣ a 1 ∣ a 2 a_0|a_1|a_2 a0a1a2 a 0 ∣ a 1 ∣ a 2 ∣ a 3 a_0|a_1|a_2|a_3 a0a1a2a3 a 0 ∣ a 1 ∣ a 2 ∣ a 3 ∣ a 4 a_0|a_1|a_2|a_3|a_4 a0a1a2a3a4 a 1 ∣ a 2 ∣ a 3 ∣ a 4 ∣ a 5 a_1|a_2|a_3|a_4|a_5 a1a2a3a4a5

不难看出, m m m每增大 1 1 1,数列的每一项就会同时向左右扩展

所以,我们可以得出答案:

a i ∣ a i + 1 ∣ . . . ∣ a n + m ( i = m a x ( n − m , 0 ) ) a_{i}|a_{i+1}|...|a_{n+m}(i = max(n-m,0)) aiai+1∣...∣an+m(i=max(nm,0))

然后我们考虑优化

以一组样例举例:

1145 14 (绝对不是故意的)

则按照公式有:

a n s = 1131 ∣ 1132 ∣ . . . ∣ 1158 ∣ 1159 = ( 10001101011 ) 2 ∣ ( 100010001100 ) 2 ∣ . . . ∣ ( 10010000110 ) 2 ∣ ( 10010000111 ) 2 ans = 1131|1132|...|1158|1159=(100 0110 1011)_2|(100010001100)_2|...|(100 1000 0110)_2|(10010000111)_2 ans=1131∣1132∣...∣1158∣1159=(10001101011)2(100010001100)2∣...∣(10010000110)2(10010000111)2

观察到, 1131 1131 1131 1159 1159 1159的二进制有一部分是公共的,并且后面非公共的部分每一位均出现过 1 1 1

同时,我们注意到异或 ( ⊕ ) (\oplus) ()有一个性质

a ⊕ a = 0 a \oplus a = 0 aa=0

所以,我们便可以消去前面公共的部分,然后再求出后面非公共的部分的长度(可以用对数求),构造一个与非公共部分的长度相等的全是 1 1 1的子串,再与 m a x ( a 0 , a n − m ) max(a_0,a_{n-m}) max(a0,anm)进行或运算即可(当然你也可以选其他的)

代码如下:

//#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,m,T;
signed mian()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin >> T;
    while(T--)
    {
        cin >> n >> m;
        if(m != 0)
        {
            int x = (int)(log2(max(0ll,n - m) ^ (n + m))) + 1;
            cout << ((n + m) | ((int)pow(2ll,x) - 1)) << "\n";
        }
        else cout << n << "\n";
    }
}
//禁止直接Ctrl C+V!!!

时间复杂度: O ( T ) O(T) O(T)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值