链接
http://acm.hdu.edu.cn/showproblem.php?pid=6129
题解
考虑第一个数对后面的影响,我用
a
k
a^k
ak表示
a
a
a自身异或
k
k
k次
a
,
b
,
c
a,b,c
a,b,c
a
,
a
b
,
a
b
c
a, ab, abc
a,ab,abc
a
,
a
2
b
,
a
3
b
2
c
a,a^2b,a^3b^2c
a,a2b,a3b2c
a
,
a
3
b
,
a
6
b
2
c
a,a^3b,a^6b^2c
a,a3b,a6b2c
a
,
a
4
b
,
a
10
b
3
,
c
a,a^4b,a^{10}b^3,c
a,a4b,a10b3,c
然后把
a
a
a的异或次数的矩阵写出来
1 0 0
1 1 1
1 2 3
1 3 6
1 4 10
…
其实还可以写的更宽一些(去掉第一行)
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
我自己也做到这里了,但是我就是看不出规律,我横着看竖着看,做差也看不出规律
结果上网一查题解,啥?还能斜着看?
斜着看就是杨辉三角?
算我输了
斜着看确实是杨辉三角
如果给行和列都从
0
0
0开始编号,就得到第
i
i
i行的第
j
j
j个数是
C
i
+
j
j
C_{i+j}^j
Ci+jj
那么最后一行的第
i
i
i个数就是
C
m
−
1
i
i
C_{m-1_i}^i
Cm−1ii
我只确定每个数字的奇偶性,就可以知道它对后面有没有贡献,这个可以直接数阶乘里的
2
2
2的个数
如果一个这个系数是奇数,那就把这个地方设为
1
1
1,否则设为
0
0
0
然后后面的数的系数就是第一个系数的平移,我现在要算出最后每个数值
然后就不会了,感觉这东西类似多项式卷积的计算,确要让你异或
看了看题解,竟然都是暴力?
貌似是因为大多数系数都等于 0 0 0只有少数等于 1 1 1吧
太神了这题
代码
#include <bits/stdc++.h>
#define maxn 200010
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
ll c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
ll n, a[maxn], m;
ll count2(ll x)
{
ll ans(0);
while(x)
{
ans+=x>>1;
x>>=1;
}
return ans;
}
ll calc(ll n, ll m)
{
ll ans=count2(n)-count2(m)-count2(n-m);
return ans;
}
ll ans[maxn], c[maxn];
int main()
{
ll i, j, T=read();
while(T--)
{
n=read(), m=read();
for(i=0;i<n;i++)a[i]=read();
cl(ans);
for(i=0;i<n;i++)
{
auto t=calc(m+i-1,i);
if(t==0)
{
for(j=i;j<n;j++)
{
ans[j]^=a[j-i];
}
}
}
for(i=0;i<n;i++)
{
printf("%lld",ans[i]);
if(i<n-1)putchar(32);
}
putchar(10);
}
return 0;
}