P3908 数列之异或【连续异或O(1)做法】

P3908 数列之异或


  • 题意:输入n,输出数列{1, 2, 3, ... , n}异或的结果

如何O(1)做?

(1)、

我们知道如果某个数n为奇数,那么n-1为偶数,并且n^(n-1)==1【不知道自己写一下就知道了,因为非负整数是从0开始的】

所以对于这道题来说,如果n为奇数,那么我们只需要数一下有多少个奇数即可

如果n为偶数,那么就强制n=n-1为奇数,同上解决,最后再异或一个n+1即可

 

    ll n, ans; n = read();
    bool even = false;
    if(!(n & 1)) --n, even = true;
    if((n + 1) >> 1 & 1) //奇数个1
        ans = 1;
    else
        ans = 0;
    if(even) cout << (ans ^ (n + 1));
    else cout  << ans;

 

(2)、

dl总结出的规律,证明就不给了,很D区 

    ll n; n = read();
    switch(n % 4)
    {
        case 0: cout << n << '\n'; break;
        case 1: cout << "1\n"; break;
        case 2: cout << n + 1 << '\n'; break;
        case 3: cout << "0\n"; break;
    }

 其实两者很相像的!第一种很容易理解,可以由第一种打表看一下,第二种的规律总结也很显然。【果然还是数学归纳法最香了~


整代码

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

typedef long long ll;

inline ll read()
{
    ll x = 0, f = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}

const int maxN = 100005;

int main()
{
//    ll n, ans; n = read();
//    bool even = false;
//    if(!(n & 1)) --n, even = true;
//    if((n + 1) >> 1 & 1) //奇数个1
//        ans = 1;
//    else
//        ans = 0;
//    if(even) cout << (ans ^ (n + 1));
//    else cout  << ans;
    ll n; n = read();
    switch(n % 4)
    {
        case 0: cout << n << '\n'; break;
        case 1: cout << "1\n"; break;
        case 2: cout << n + 1 << '\n'; break;
        case 3: cout << "0\n"; break;
    }
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值