hdu 6129 Just do it

来源:互联网 发布:idea创建web项目ubuntu 编辑:程序博客网 时间:2024/04/26 16:05

http://acm.hdu.edu.cn/showproblem.php?pid=6129
Problem Description
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.

Input
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×105,1≤m≤109).
The second line contains n nonnegative integers a1…n(0≤ai≤230−1).

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

Sample Input
2
1 1
1
3 3
1 2 3

Sample Output
1
1 3 1

题目大意:给你一个数列a长度为n,将b【i】 = a【1】^……^a[i];以这样的规则对a数列求m次异或和,得到b数列

解题思路:
这里写图片描述
我们先只看每次异或后1这个元素被异或的次数
第一次:1 1 1 1
第二次:1 2 3 4
第三次:1 3 6 10
第四次:1 4 10 20
可以发现这些数字是有规律的。用i表示第几次疑惑,j表示第几个元素
则每次的系数为C(i+j-2,j-1);我们知道偶数个相同的元素异或结果为0,而0和任何数异或,原数不变。奇数个相同的元素异或结果为原数,对结果有影响(元素 2 3 4 的规律也一样) 。现在我们的任务就是判断每个元素的系数是奇数还是偶数就可以了。根据lucas定理可得若(i+j-2)&(j-1)=(j-1)时C(i+j-2,j-1)为奇数,否则为偶数。

#include <bits/stdc++.h>using namespace std;int a[200005],b[200005];int main(){    int T;scanf("%d",&T);    while(T--)    {        memset(b,0,sizeof(b));        int n,m;scanf("%d %d",&n,&m);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        for(int i=1;i<=n;i++){            if(((m+i-2)&(i-1))==(i-1))///判断当前这个元素对第i个元素有没有影响                for(int j=i;j<=n;j++)                    b[j] = b[j]^a[j-i+1];        }        printf("%d",b[1]);        for(int i = 2; i <= n; i++)            printf(" %d",b[i]);        printf("\n");    }}
原创粉丝点击