(2017多校训练第七场)HDU - 6129 Just do it

题意:

给出 n,m , 和 a1,a2.........an

每次操作都会有,bi=a1^a2^a3^...ai    ('^'为异或)

求m次操作后的序列

思路:

比赛的时候一直在想找规律,发现了循环,就觉得这是正确方向,最后可以在O(n)的复杂度,知道m后bi由那些数异或而成,这时才发现即使知道了也要O(n2)的遍历才可以得出最后的序列,这时发现方向错了。。。。期间队友还提过组合数判断奇偶。。。。我居然反对了。。。。。我的锅我的锅。。。。

赛后补题

这时才想到,正确的方向应该是看某个数对答案序列的那些元素有贡献

我们可以轻易的把5X5的表手打出来

10000    10000   10000     1    0  0 0 0

01000    10000   21000     3    1  0 0 0

00100    10000   32100     6    3  1 0 0

00010    10000   43210     10  6  3 1 0

00001    10000   54321     15 10 6 3 1

我们从这几个可以看出每一行的系数 都是下一行的左移动一格

而每个最后一行我们都可以轻易的手打出表来,其实数学思维强的可能已经看来了

 1   1   1     1     1             1  / 1 / 1  / 1  /  1                                   c0,0  / c1,1 / c,2,2  / c3,3  /  c4,4       

 1   2   3     4      5              /1  / 2  /  3 /  4   /  5                                    / c1,0  / c2,1  /  c3,2 /  c4,3   /  c5,4

 1   3   6    10    15                /1   / 3  /  6   / 10  / 15                                      / c2,0  / c3,1  /  c4,2   / c5,3  / c6,4

 1  4  10    20    35                    /1   /  4   / 10  / 20  / 35                                         /c3,0   /  c4,1   / c5,2  / c6,3  / c7,4

 1  5   15    35   70                        /  1   /   5  / 15   / 35  /  70                                         /c4,0      /  c5,1 / c6,2  / c7,3  / 

我们发现每个数都是它上面的数和左边的数之和,一个杨辉三角,组合数

m次过后   ,假设   j=i+t    那么  i对j的贡献就是C m+t , t  次

刚刚才学到C(n, m)为奇数等价于n & m == m

我们遍历t(0~n) 

根据C m+t , t是否为奇数来判断是否 有  对于 每个 (j>i) ans[j]^=a[j-t]

#include<bits/stdc++.h>
#define N 200009
using namespace std;
long long a[N],ans[N];
int main()
{
	int T,n,m,x,y;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
		{
		scanf("%lld",a+i);		
		ans[i]=a[i];	
		}
		if(m!=0)
		{
			m--;
			for(int i=1;i<n;i++)
			{
				x=i;
				y=m+i;
				if((x&y)==x)
				{
				   for(int j=i+1;j<=n;j++)
					ans[j]^=a[j-i];	
				}
			}
		}
		  for (int i = 1; i <=n; i++)  
         printf("%lld%c", ans[i], " \n"[i==n]); 
	}
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值