[JLOI2011]不重複數字 題解

前言

本題是一道哈希表的模板題。然而當時的 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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章