题解 P3937 【Changing】
很容易发现,每一个时间的操作就是异或
那么我们直接考虑异或是模
可以发现我们操作的序列是这样的序列(下面仅展现一部分,太丑了
我们可以发现这个和杨辉三角的递推过程是等价的
那么就可以说明,是让我们求其中一些位置和杨辉三角的某些项的乘积和
考虑到我们最后要对
我们可以发现,全
然而上面的并没有p用,又考虑到直接预处理阶乘求组合数不太可行,因为偶数在此意义下没有逆元
我们直接考虑组合数公式
实际就是看上下的 we数组表示 lowbit来预处理阶乘的
然后就可以暴力
#include <cstdio>
using namespace std;
int n,t,k;
int zb,zl;
int a[3000010],fra[3000010],we[5000010],ans;
int lowbit(int x)
{
return x&(-x);
}
void init()\\这里是预处理2因子数量
{
for(int i=1;i<=21;i++) we[1<<i]=i;
fra[0]=0;
for(int i=1;i<=t+1;i++) fra[i]=fra[i-1]+we[lowbit(i)];
}
int get(int x)
{
if(fra[t]-fra[x-1]-fra[t-x+1]>0) return 0;
return 1;
}
int main()
{
scanf("%d%d%d",&n,&t,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
init();
for(int i=1;i<=t+1;i++) ans=(ans+a[(k+i-2)%n+1]*(get(i))%2)%2;
printf("%d",ans);
}
update:
今天翻看资料的时候发现,这东西叫做Sierpinski三角形
然后发现这个东西有很nb的结论来看
看这里:http://www.matrix67.com/blog/archives/280
#include <cstdio>
using namespace std;
int n,t,k;
int a[3000010],fra[3000010],we[5000010],ans;
int get(int x)
{
if(((x-1)&t)==(x-1)) return 1;
return 0;
}
int main()
{
scanf("%d%d%d",&n,&t,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
init();
for(int i=1;i<=t+1;i++) ans=(ans+a[(k+i-2)%n+1]*(get(i))%2)%2;
printf("%d",ans);
}