LOJ 6087. 毒瘤題 (數論)
阿新 • • 發佈:2019-02-13
題目描述
傳送門
題目大意:在集合中找出 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);
}