1. 程式人生 > >【BZOJ 3687】簡單題

【BZOJ 3687】簡單題

題目描述

小呆開始研究集合論了,他提出了關於一個數集四個問題: 1.子集的異或和的算術和。 2.子集的異或和的異或和。 3.子集的算術和的算術和。 4.子集的算術和的異或和。 目前為止,小呆已經解決了前三個問題,還剩下最後一個問題還沒有解決,他決定把這個問題交給你,未來的集訓隊隊員來實現。 ai>0a_i\gt 01<n<10001\lt n\lt 1000ai2000000\sum a_i\le 2000000,另外,不保證集合中的數滿足互異性,即有可能出現 ai=aja_i=a_jii 不等於 jj

演算法分析

觀察到和最大是 20000002000000,考慮對於每個和計算它對答案的貢獻,如果它被累加進答案的次數為奇數個那麼就對答案有貢獻,否則由於異或的性質抵消,同樣是列舉每個數選或不選的 0/1 揹包模型,由於我們只記錄奇偶性,可以使用 bitset 壓縮,同時用異或運算替代加法對 22 取模的運算。

程式碼實現

#include <cstdio>
#include <bitset>
std::bitset<(int)2e6+5> f;
int main() {
	int n;scanf("%d",&n);f[0]=1;
	for(int i=1;i<=n;++i) {
		int
a;scanf("%d",&a); f^=f<<a; } int ans=0; for(int i=1;i<=(int)2e6;++i) if(f[i]) ans^=i; printf("%d\n",ans); return 0; }