loj6537. 毒瘤題加強版再加強版
阿新 • • 發佈:2020-07-09
題意:對於一個\(n\)個數的可重集,求出所有\(k\)個出現次數為奇數的數\(a\)。
\(n \leq 3\times 10^6,k \leq 5000\),memory limit=3MiB。
題解:顯然無法開下長為\(n\)的陣列。那麼考慮用雜湊表進行壓縮。也就是給每個數一個\(key,value\)。
考慮如何統計出現次數為奇數。可以找到\(key\)值後進行異或操作,異或一個\(value\)。
考慮存在雜湊衝突,那麼我們多開幾個雜湊表就行了。
最後統計時,直接列舉所有雜湊表的所有\(key\),找到其對應的\(value\)即可,答案用set存一下就好了。
程式碼:
#include<bits/stdc++.h> using namespace std; #define re register int #define F(x,y,z) for(re x=y;x<=z;x++) #define FOR(x,y,z) for(re x=y;x>=z;x--) typedef long long ll; #define I inline void #define IN inline int #define C(x,y) memset(x,y,sizeof(x)) #define STS system("pause") template<class D>I read(D &res){ res=0;register D g=1;register char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')g=-1; ch=getchar(); } while(isdigit(ch)){ res=(res<<3)+(res<<1)+(ch^48); ch=getchar(); } res*=g; } const ll INF=998244353,P=2048576; ll c[7]={0,29131,29947,29663,26399,28151,28669}; int n,m;ll w,v,f[7][30300]; set<int>s; int main(){ read(n);read(m); while(n--){ read(w); F(i,1,6)v=w*INF+P,f[i][w%c[i]]^=v; } F(i,1,6)F(j,0,c[i]-1){ w=f[i][j]/INF;if((f[i][j]%INF)==P&&!s.count(w))s.insert(w); } for(auto it=s.begin();it!=s.end();it++)cout<<*it<<endl; return 0; }