题目

有 n 个红球, m 个蓝球,从中取出 x 个红球和 y 个蓝球排成一排的得分是 rx⋅by ,其中 r0=b0=1 。
定义 f(t) 表示恰好取出 t 个球排成一排的所有可能局面的得分之和。
两个局面相同,当且仅当这两排球的个数相等,且在对应列位置上的颜色都是相同的。
小Q想知道,有多少 t (1≤t≤n+m) 使得 f(t) 是奇数,你能告诉他满足条件的 t2 之和吗?
对于样例, f(1)=2,f(2)=5,f(3)=13,f(4)=28,f(5)=50,f(6)=60 ,答案是 $22+32=13 $。

分析

cty爆音通道 to 分治做法什么的看到我一脸懵逼
于是只能打个FWT
题目中的\(f(t)=\sum_{x+y=t}r_xb_yC_{t}^{x}\),这个不用多解释。
然后考虑如何判断\(f(t)\)是否为奇数,
因为只用判断奇偶,只用保留%2的结果。
据说根据lucas定理得出,\(C_{n+m}^n\)为奇数,尤其尤其仅当\([x\ and\ y=0]\)
于是
原式得

\[f(t)=\sum_{x+y=t}r_xb_y[x\ and\ y=0] \]

\[=\sum_{x+y=t}r_xb_y[x\ or\ y=t] \]

\[=\sum_{x\ or\ y=t}r_xb_y[x+y=t] \]

设\(bit(i)\)表示二进制下i的1的个数

\[=\sum_{x\ or\ y=t}r_xb_y[bit(x)+bit(y)=bit(t)] \]

然后考虑如何用FWT处理这个,
我们让\(rr_{bit(i),i}=r_i,bb_{bit(i),i}=b_i,其余为0\)
然后,对于\(rr_{bit(0-20)},bb_{bit(0-20)}\), 都做一次FWT,
接着,对于\(f_{bit(t),i}=\sum_{bit(x)+bit(y)=bit(t)}rr_{bit(x)}bb_{bit(y)}\)
最后UFWT。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <bitset>
const int maxlongint=2147483647;
const int mo=1e9+7;
const int N=2200005;
const int M=1<<8;
using namespace std;
#define sqr(x) (1ll*(x)*(x))
int n,m,r[N],b[N],fn,bit[N];
long long ans;
int rr[23][N>>3],bb[23][N>>3],v[4],mi[10];
int val(int i,int j)
{
	return (i<<3)+7-j;
}
void read(int *a,int n)
{
	for(int i=1;i<=n;i++)
	{
		char c=getchar();
		for(;c<'0' || c>'9';c=getchar());
		a[i]=c-'0';
	}
}
void FWT(int *f)
{
	for(int len=1;len<=3;len++)
		for(int i=0;i<fn>>3;i++)
			f[i]^=(f[i]&v[len])>>(1<<(len-1));
	for(int len=2;len<=fn>>3;len<<=1)
	{
		int half=len>>1;
		for(int i=0;i<half;i++)
			for(int j=i;j<fn>>3;j+=len) f[j+half]^=f[j];
	}
}
int main()
{
	freopen("1824.in","r",stdin);
	freopen("1824.out","w",stdout);
	scanf("%d%d",&n,&m);
	fn=1<<21,v[1]=170,v[2]=204,v[3]=240;
	mi[0]=1;
	for(int i=1;i<=8;i++) mi[i]=mi[i-1]<<1;
	for(int i=0;i<=fn;i++)
		for(int x=i;x;x&=x-1,bit[i]++);
	r[0]=b[0]=1;
	read(r,n),read(b,m);
	for(int i=0;i<fn>>3;i++)
		for(int j=7;j>=0;j--) 
			rr[bit[val(i,j)]][i]^=(r[val(i,j)]&1)*mi[j],bb[bit[val(i,j)]][i]^=(b[val(i,j)]&1)*mi[j];
	for(int i=0;i<=20;i++) FWT(rr[i]),FWT(bb[i]);
	for(int i=0;i<fn>>3;i++)
	{
		for(int k=20;k>=0;k--)
		{
			int tmp=0;
			for(int j=0;j<=k;j++)
				tmp^=bb[k-j][i]&rr[j][i];
			rr[k][i]=tmp;
		}
	}
	for(int i=0;i<=20;i++) FWT(rr[i]);
	for(int i=0;i<fn>>3;i++)
		for(int j=7;j>=0;j--)
			if(val(i,j)<=n+m)
				if(rr[bit[val(i,j)]][i]&mi[j]) ans+=sqr(val(i,j));
	printf("%lld\n",ans);
}

相关文章:

  • 2022-12-23
  • 2022-03-08
  • 2022-02-13
  • 2021-12-01
  • 2022-01-18
  • 2021-09-18
猜你喜欢
  • 2021-05-30
  • 2021-11-18
  • 2022-01-10
  • 2021-10-30
  • 2021-12-25
  • 2021-08-24
  • 2021-12-19
相关资源
相似解决方案