HDU 6129

Just do it

时间限制: 5 Sec   内存限制: 128 MB

题目描述

There is a nonnegative integer sequence  a1...n of length  n. HazelFan wants to do a type of transformation called prefix-XOR, which means  a1...n changes into  b1...n, where  bi equals to the XOR value of  a1,...,ai. He will repeat it for  m times, please tell him the final sequence.
 

输入

The first line contains a positive integer  T(1≤T≤5), denoting the number of test cases.
For each test case:
The first line contains two positive integers  n,m(1≤n≤2×10^5,1≤m≤10^9).
The second line contains  n nonnegative integers  a1...n(0≤ai≤2^30−1).
 

输出

For each test case:
A single line contains  n nonnegative integers, denoting the final sequence.
 

样例输入

2
1 1
1
3 3
1 2 3

样例输出

1
1 3 1


题意:

给定一个数组a,然后要求出数组b,数组b于数组a之间满足这样的规律:
b[i]=a[1]^a[2]^·····^a[i].

但是并非求经过一次转换后的b[i],而是经过每次的转换m次后的b[i]


解题思路:如果直接暴力,会超时。

如果我们假设数组a的元素分别为:a b c d;

第一次转换后:a a^b a^b^c a^b^c^d;

第二次转换后:a a^a^b a^a^a^b^b^c a^a^a^a^b^b^b^c^c^d;

若设列为i,行为j很显然,所求位置(i,j)=(i,j-1)+(i-1,j);所以可以发现这是杨辉三角

可以发现第x次变换第y项是C(x+y-2,y-1)

对于C(n,m),如果n&m==m则C(n,m)为奇数。

若为奇数则贡献,若为偶数异或后为零不贡献

以上讨论是考虑第一项(a)对所有位子的结果的影响即可(因为b就相当于向后挪了一下递推即可)


源代码:

#include<iostream>
#include<cstdio>
#include<cstring>
const int M=2e6+1;
int a[M],b[M];
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {

        int n,m;
        scanf("%d%d",&n,&m);
        memset(b,0,sizeof(b));
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        for(int i=0;i<n;i++)//第m次异或第i项
        {
            int y=i;
            int x=i+m-1;
            if((x&y)==y)
            {
                for(int j=i;j<n;j++) b[j]^=a[j-i];
            }
        }
        for(int i=0;i<n;i++)
            printf("%d%c",b[i],i==n-1?'\n':' ');
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值