noj 2107 有趣的区间异或值(异或,找规律)

有趣的区间异或值

时间限制(普通/Java) :  2000 MS/ 6000 MS          运行内存限制 : 65536 KByte
总提交 : 354            测试通过 : 35 

比赛描述

按照下列规则生成一个序列,当x > 0时 A[x] = A[x-1] xor x,当x == 0时,即A[0] = 0,当然,题目没有这么简单,有n组查询,对于每组询问L,R,就要输出序列A[L] xor A[L+1] xor A[L+2]...xor A[R-1] xor A[R],即这个序列下标在[L,R]区间内的异或值。




输入

第一行一个数字N,表示N组询问(N <= 105),接下来N行,第i行给出第i组询问的L,R(1<=L<=R<=109)


输出

输出N行,每行一个数,即序列下标在[L,R]区间内的异或值



样例输入

4
1 5
2 8
3 10
10 100

样例输出

7
9
0
111

题意:中文题不解释

思路:直观看这道题没什么思路,想到是异或可能有规律,于是打表找规律之。

果然,Ai是每隔4个出现一个0,前缀和是每隔8个出现一个0

那么4和8就分别是这两个的循环节了,处理一下就好

对于l~r这个区间我们可以简单化,结果为xo(r)-xo(l-1),利用了0~l-1这段区间异或两次变成0的性质

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
void init()
{
    int n=0,sum=0;
    for(int i=1; i<=100; i++)
    {
        printf("%d %d\n",n,sum);
        n^=i;
        sum^=n;
    }
}
long long xo(int x)///A0xorA1...xorAx
{
    long long n=0,sum=0;
    if(x<=7)
        for(int i=1; i<=x; i++)
            {
                n^=i;
                sum^=n;
            }
    else
    {
        int m=x;
        m-=7;
        int pos=m%8;
        if(x<4)
            for(int i=1; i<=x; i++)
                n^=i;
        m-=3;
        int pos1=n%4;
        for(int i=x-pos1+1; i<=x; i++)
                n^=i;
        for(int i=x-pos+1; i<=x; i++)
            {
                n^=i;
                sum^=n;
            }
    }
    return sum;
}
int main()
{
    int T,l,r;
    //init();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&l,&r);
        printf("%lld\n",xo(r)^xo(l-1));
    }
    return 0;
}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值