1. 程式人生 > >LOJ 6087. 毒瘤題 (數論)

LOJ 6087. 毒瘤題 (數論)

題目描述

傳送門

題目大意:在集合中找出 k (k≤2)個出現了奇數次的正整數 a。
注意記憶體:2MB

題解

當k=1的時候,我們可以對所有的數求異或和,得到的異或和即為a,因為出現偶數次的都兩兩消掉了。
k=2的時候,我們得到的異或和是a^b。
對於二進位制的每一位維護cnt[i]表示有多少數二進位制的第i位中1,c[i]表示所有第i位為1的數的異或和。
如果ans中某一位是1,那麼說明a,b兩個數中有一個數該位是1,那麼對應的c[i]就是其中一個數的答案。對應ans取異或就可以得到另一個數的答案。

程式碼

#include<cstdio>
#include<algorithm>
using namespace std; int c[37],cnt[37],n,k,ans; int main() { freopen("a.in","r",stdin); scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) { int x; scanf("%d",&x); ans=ans^x; for (int i=0;i<=31;i++) if ((x>>i)&1) c[i]^=x,cnt[i]++; } if
(k==1) { printf("%d\n",ans); return 0; } int a,b; for (int i=31;i>=0;i--) if (cnt[i]%2) a=c[i]; b=ans^a; if (b<a) swap(a,b); printf("%d %d\n",a,b); }