前言
本題是一道哈希表的模板題。然而當時的 data maker 竟然連直接開桶的做法都沒有卡掉...
於是在 Luogu 上,很長一段時間之內,這道題的最優解一直是這個錯解。
而且,雖然題面上寫着給出的數在 32 位有符號整數範圍內
,但是 data maker 也沒有出出來負數...導致一些錯誤的哈希表做法也 AC 了(比如說我之前的哈希表代碼)。
然後今天凌晨偶然看到了這道題目,重新寫了一遍之後,提交到 Luogu 上面去,發現炸成了 60 分!
看了一眼之前的提交記錄:怎麼哈希表做法都炸成 60 分了?只有幾個 map 在那裏苟延殘喘。
然後提交到了 BZOJ 上,發現 AC 啦!於是一度以爲 Luogu 數據錯了!然而發現評論區一車人說 60 分的,於是又翻了一會帖子,發現管理員改了數據!
QAQ...於是改了一會,發現這個哈希函數在接收負數時會出現負數的數組下標!然而自己負數取模都寫錯了 2 遍。
當然,最後還是 AC 啦,故作文以記之。
正文
水題。每次讀入一個數,就嘗試插入哈希表。如果已經在哈希表中出現了,即取消插入。否則,插入後直接輸出該數即可。
需要注意的是,此題數據範圍極大,所以需要使用較快的讀入方式。
Code:
#include <bits/stdc++.h>
using namespace std;
const int P=50021;
#define int long long
struct node {int v,nxt;}rec[10+P];
int hd[10+P],n;
namespace HASH {
int tot;
int H(int x) {return (x%P+P)%P;}
bool add(int x, int v) {
for (int i=hd[x];i;i=rec[i].nxt) if (rec[i].v==v) return false;
rec[++tot].v=v;
rec[tot].nxt=hd[x];
hd[x]=tot;
return true;
}
}
using HASH::tot;
using HASH::H;
using HASH::add;
void rd(int&),wt(int);
#undef int
int main() {
#define int long long
int T;rd(T);
while(T--) {
tot=0;memset(rec,0,sizeof rec);memset(hd,0,sizeof hd);rd(n);
while (n--) {
int x;rd(x);
if (add(H(x),x)) wt(x),putchar(' ');
}
puts("");
}
return 0;
}
void rd(int& x) {
x=0;int f=1;char ch=getchar();
while (!isdigit(ch)) (ch=='-')&&(f=-1),ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x*=f;
}
void wt(int x) {
(x<0)&&(x=-x,putchar('-'));
if (x>9) wt(x/10);putchar(x%10^48);
}