K-MORE XOR(找规律) 2019南昌邀请赛网络赛

题目链接:哆啦A梦传送门

题意:给出三个函数:

{\color{Red} f(l,r)=\bigoplus ax(l=<x<=r) }

{\color{Red} g(l,r)=\bigoplus f(x,y) (l<=x<=y<=r)}

{\color{Red} w(l,r)=\bigoplus g(x,y) (l<=x<=y<=r)}

q次询问,每个输出w(x,y)的结果。

 

题解:

这题可以通过一系列的化简得到最简表达式。先给出结论,再解释。

对于询问 w(x,y) :首先我们 令len=y-x+1len2=(y-x)/2+1

1,假设len为奇数,那么此时w(x,y)等价于

f(x,x)^f(x,x+2)^f(x,x+4)^...^f(x,x+2*i) (x+2*i<=y)

      f(x+2,x+2)^f(x+2,x+4)^...^f(x+2,x+2*i) (x+2*i<=y)

                        f(x+4,x+4)^...^f(x+4,x+2*i) (x+2*i<=y)                                         

                                                  f(y,y)

 

2,假设len为偶数,那么此时w(x,y)等价于

f(x,x+1)^f(x,x+3)^f(x,x+5)^...^f(x,x+2*i+1) (x+2*i+1<=y)

      f(x+2,x+3)^f(x+2,x+5)^...^f(x+2,x+2*i+1) (x+2*i+1<=y)

                        f(x+4,x+5)^...^f(x+4,x+2*i+1) (x+2*i+1<=y)                                         

                                                  f(y-1,y)

 

这里是化成第一步,它还可以再消去的,然后我们再分一次奇偶。所以总共有4种情况。

 

one:len为奇数,len2也为奇数,w(x,y)= ax^a(x+4)^...^ay。

two:len为奇数,len2为偶数, w(x,y)=a(x+1)^a(x+1+4)^...^a(y-1)。

three:len为偶数,len2为奇数,w(x,y)=ax^a(x+4)^...^ay^a(x+1)^a(x+1+4)^...^a(y-1)。

four:len为偶数,len2为偶数,w(x,y)=0。

 

故我们只需预处理扫一遍就可以 O(1)解决了。

现在我们解释一下是怎么通过判断len的奇偶性来找到上三角的呢?很简单,想几个数据,对着9*9乘法表一直化简。

例如:w(3,7),它等价于下面所有函数的异或

列:

1            2        3         4        5

g(3,3) g(3,4) g(3,5) g(3,6) g(3,7)

           g(4,4) g(4,5) g(4,6) g(4,7)

                      g(5,5) g(5,6) g(5,7)

                                 g(6,6) g(6,7)

                                             g(7,7)

 

我们每列每列的消去,最后得到:

f(3,3)  f(3,3)  f(3,3)  f(3,3)  f(3,3)  

           f(3,4)  f(3,4)  f(3,4)  f(3,4)  

                     f(3,5)  f(3,5)  f(3,5)  

                     f(5,5)  f(3,6)  f(3,6) 

                               f(5,5)   f(3,7)

                               f(5,6)   f(5,5)

                                          f(5,6)

                                          f(5,7)

                                         f(7,7)

最后我们把这些重复的偶数项给消去,就得到上面的式子了。

 

#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

typedef long long LL;
const int maxn=1e5+10;


LL a[maxn],sum[maxn];
///sum[i]表示 a[i]^a[i-4]^...

int main()
{
        int ncase,n;

    scanf("%d",&ncase);

    while(ncase--)
    {
        scanf("%d",&n);

        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);

            memset(sum,0,sizeof(sum));

        for(int i=1;i<=n;i++)
        {
            if(i<=4) sum[i]=a[i];
            else sum[i]=sum[i-4]^a[i];
        }

        int q,x,y;
        scanf("%d",&q);

        while(q--)
        {
            scanf("%d%d",&x,&y);

            int len=y-x+1,len2;
            LL ans;
            
            if(len%2)
            {
                len2=(y-x)/2+1;
                if(len2%2)
                {
                    ans=sum[y];
                    if(x>=4)
                        ans^=sum[x-4];

                    printf("%lld\n",ans);
                }
                else{
                    ans=sum[y-1];
                    if(x+1>=4)
                    ans^=sum[x-3];
                    printf("%lld\n",ans);

                }
            }
            else{
                len2=(y-x)/2+1;
                if(len2%2)
                {
                    ans=sum[y];
                    if(x>=4)
                        ans^=sum[x-4];

//                        printf("%lld\n",ans);
                    ans^=sum[y-1];

                    if(x+1>=4)
                        ans^=sum[x-3];
                        printf("%lld\n",ans);
                }
                else{
                    puts("0");

                }
            }
        }
    }
}


 

 

 

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值