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
#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;
}