hdu 6129 杨辉三角(递推好题)

Just do it

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 579    Accepted Submission(s): 319


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(1T5), denoting the number of test cases.
For each test case:
The first line contains two positive integers n,m(1n2×105,1m109).
The second line contains n nonnegative integers a1...n(0ai2301).
 

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,然后求其异或前缀和,再求异或前缀和的前缀和,这么继续m次,求最后的数列

题解:

根据下图,我们可以发现,每一个格子里面的系数都是等于它上面格子相应系数加上左边格子相应系数的和(和杨辉三角的递推式很相似)

推得每一个系数的组合数C(m+i-2 , i-1),i 表示某一初始数列在位置x,对后面第 i 列的贡献值

但是若暴力枚举X,很容易超时,所以我们枚举 i ,当C(m+i-2 , i-1)为奇数的时候才算贡献值,偶数的时候不算

因为偶数个相同的数字异或后的结果不变

而判断C(m+i-2 , i-1)是奇数还是偶数可以通过判断与值是否等于i-1

t=((i-1)&(m+i-2))==(i-1)?1:0;
当得到1的时候可以为奇数,0的时候为偶数

这个定理的证明我们可以用在杨辉三角中进行数学归纳



注意,下面第二列第一个数是a1,第二个才是a2,我写错了,不想改了,不好意思


hdu 6129 杨辉三角(递推好题)_第1张图片





#include

#define MAXN 200005
int a[MAXN],ans[MAXN];

int main()
{
    int T;
    int n,m,t;
    //freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),ans[i]=a[i];
        for(int i=2;i<=n;i++){///枚举i,计算第j-i+1个数对后面第i列贡献
            t=((i-1)&(m+i-2))==(i-1)?1:0;
            if(t){
                for(int j=i;j<=n;j++)
                    ans[j]^=a[j-i+1];
            }
        }

        for(int i=1;i<=n;i++)
            printf("%d%c",ans[i],i==n?'\n':' ');
    }
    return 0;
}


你可能感兴趣的:(组合数学,acm)