AtCoder Beginner Contest 228 D - Linear Probing
阿新 • • 發佈:2021-12-16
題意
給定一個序列A和N=2^20,A的範圍為[0,N-1],初始值均為-1。
操作1:設h=x(給出),如果a[h%MOD]!=-1就h+1,直到a[h%MOD]==-1為止。之後,設a[h%MOD]的值為x。
操作2:輸出a[x%MOD]。
資料範圍:x>=0,保證操作1有答案。
題解
性質1:不能打暴力(時間複雜度超額)
性質2:只要a[h]的值被設定,a[h]就不會再在判斷a[h%MOD]時不斷+1。
性質3(性質1、2):對於每個h,如果a[h]==-1,那麼它就要連到a[h]!=-1的一個點去。
答案1(性質3):考慮使用並查集維護連通性。
值得注意的是,在使用並查集維護連通性時,由於(x%MOD)本身具有自環的性質,那麼f[x%MOD]=f[(x+1)%MOD]即可。
#include<cstdio> #include<iostream> #include<algorithm> #define int long long using namespace std; const int MOD = 1 << 20; int a[MOD]; int f[MOD]; int find(int x) { while (f[x] != x) { x=f[x] = f[f[x]]; } return f[x]; } void init() { for (int i = 0; i < MOD; i++) { a[i] = -1; f[i] = i; } } void add(int x) { int h = find(x%MOD); a[h%MOD] = x; f[h%MOD] = f[(h + 1) % MOD]; } int val(int x) { return a[x%MOD]; } signed main() { init(); int q; scanf("%lld", &q); for (int i = 1; i <= q; i++) { int t, x; scanf("%lld%lld", &t, &x); if (t == 1) { add(x); } if (t == 2) { printf("%lld\n", val(x)); } } return 0; }
TRANSLATE with x English TRANSLATE with EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back