[ARC156D] Xor Sum 5

Problem Statement

You are given a sequence of N non-negative integers A=(A1,A2,,AN) and a positive integer K.

Find the bitwise XOR of i=1KAXi over all NK sequences of K positive integer sequences X=(X1,X2,,XK) such that 1XiN (1iK).

What is bitwise XOR?

The bitwise XOR of non-negative integers A and B, AB, is defined as follows:

  • When AB is written in base two, the digit in the 2k's place (k0) is 1 if exactly one of the digits in that place of A and B is 1, and 0 otherwise.
For example, we have 35=6 (in base two: 011101=110).
Generally, the bitwise XOR of k non-negative integers p1,p2,p3,,pk is defined as (((p1p2)p3)pk). We can prove that this value does not depend on the order of p1,p2,p3,,pk.

Constraints

  • 1N1000
  • 1K1012
  • 0Ai1000
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format:

$N$ $K$
$A_1$ $A_2$ $\dots$ $A_N$

Output

Print the answer.


Sample Input 1

2 2
10 30

Sample Output 1

40

There are four sequences to consider: (X1,X2)=(1,1),(1,2),(2,1),(2,2), for which AX1+AX2 is 20,40,40,60, respectively. Thus, the answer is 20404060=40.


Sample Input 2

4 10
0 0 0 0

Sample Output 2

0

Sample Input 3

11 998244353
314 159 265 358 979 323 846 264 338 327 950

Sample Output 3

236500026047

看着样例,会发现根据异或的性质,很多情况都会被约掉。

那么推一波生成函数,最终 S 是否有有贡献,就要看 [xS](i=1nxai)K 为奇数还是偶数。

(x1+x2++xn)2=x12+x22++xn2+2()=x12+x22++xn2

同理,(x1+x2++xn)2k=x12k+x22k++xn2k

可以对 K 进行二进制分解后套入这个式子,然后考虑他的实际意义。此时将 K 拆为 2k1+2k2++2kn,那么将题目改为如果将 K 个数分成很多段,每一段的长度都是2的正整数幂,且填一样的数,答案不变。

这个结论也有感性的理解方式。可以通过二进制分组的方式,给所有不满足这个要求的序列某两个数交换一下,和不变,异或和消掉。所有不满足要求的序列都能一一对应上。

所以知道这个后,可以数位 dp。定义 dpi,j 为考虑到第 i 位,目前所有进位+填入的 a 的和为 j 的方案数。如果 iK 二进制分组后的部分,那么就可以枚举新选什么数。同时统计答案时,注意到这里真正的方案数要乘上 n 的一个次方,所以如果 n 为奇数或者这里是 K 的最大的一个二进制位时,才会统计入答案。

#include<bits/stdc++.h>
using namespace std;
const int N=4005;
long long k,ans;
int n,a[N],dp[55][N];
int main()
{
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	dp[0][0]=1;
	for(int i=0;i<=50;i++)
	{
		for(int j=0;j<1024;j++)
		{
			if(!dp[i][j])
				continue;
			if(k>>i&1)
			{
				for(int p=1;p<=n;p++)
				{
					if((j+a[p]&1)&&(n&1||(1LL<<i+1)>k))
						ans^=1LL<<i;
					dp[i+1][j+a[p]>>1]^=1;
				}
			}
			else
			{
				if((j&1)&&(n&1||(1LL<<(i+1))>k))
					ans^=1LL<<i;
				dp[i+1][j>>1]^=1;
			}
		}
	}
	printf("%lld",ans);
	return 0;
}
posted @   灰鲭鲨  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示