-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2b86fac
commit 550d153
Showing
3 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
2018级-软件学院-算法分析与设计/E0-算法第0次练习赛-数据结构复习/BUAAOJ2371 序列并查集 路径压缩 最坏logn.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include <stdio.h> | ||
#define getchar getchar_unlocked | ||
#define putchar putchar_unlocked | ||
inline int rd() | ||
{ | ||
int k = 0; | ||
char s = getchar(); | ||
while (s < '0' || s > '9') s = getchar(); | ||
while (s >= '0' && s <= '9') k = (k << 1) + (k << 3) + (s ^ '0'), s = getchar(); | ||
return k; | ||
} | ||
inline void wr(int x) | ||
{ | ||
if (x > 9) wr(x / 10); | ||
putchar((x % 10) ^ '0'); | ||
} | ||
const int N = 200010; | ||
// worst O(\log n) average O(\alpha(n)) | ||
int n, m, cnt, l, r; | ||
namespace seg_dsu | ||
{ | ||
int f[N]; | ||
inline void init(int n) { for (int i = 1; i <= n + 1; ++i) f[i] = i; } | ||
inline int getf(int x) { return (f[x] == x) ? x : (f[x] = getf(f[x])); } | ||
inline void erase(int x) { f[x] = getf(x + 1); } | ||
inline int nxt_lower(int x) { return getf(x); } | ||
inline int nxt_upper(int x) { return getf(x + 1); } | ||
inline bool is_erased(int l, int r) { return getf(l) > r; } | ||
inline void cover(int l, int r) { for (l = nxt_lower(l); l <= r; l = nxt_upper(l)) erase(l), --cnt; } | ||
} | ||
int main() | ||
{ | ||
n = cnt = rd(), seg_dsu::init(n); | ||
m = rd(); | ||
while (m--) l = rd(), r = rd(), seg_dsu::cover(l, r), wr(cnt), putchar('\n'); | ||
} |
44 changes: 44 additions & 0 deletions
44
2018级-软件学院-算法分析与设计/E0-算法第0次练习赛-数据结构复习/BUAAOJ2371 序列并查集 路径压缩+启发式合并 最坏α(n).cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#include <stdio.h> | ||
#include <algorithm> | ||
#define getchar getchar_unlocked | ||
#define putchar putchar_unlocked | ||
inline int rd() | ||
{ | ||
int k = 0; | ||
char s = getchar(); | ||
while (s < '0' || s > '9') s = getchar(); | ||
while (s >= '0' && s <= '9') k = (k << 1) + (k << 3) + (s ^ '0'), s = getchar(); | ||
return k; | ||
} | ||
inline void wr(int x) | ||
{ | ||
if (x > 9) wr(x / 10); | ||
putchar((x % 10) ^ '0'); | ||
} | ||
const int N = 200010; | ||
// worst O(\alpha(n)) | ||
int n, m, cnt, l, r; | ||
namespace seg_dsu | ||
{ | ||
int f[N], sz[N], nxt[N]; | ||
inline void init(int n) { for (int i = 1; i <= n + 1; ++i) f[i] = i, sz[i] = 1, nxt[i] = i; } | ||
inline int getf(int x) { return (f[x] == x) ? x : (f[x] = getf(f[x])); } | ||
inline void merge(int x, int y) | ||
{ | ||
x = getf(x), y = getf(y); | ||
if (x == y) return; | ||
if (sz[x] > sz[y]) std::swap(x, y); | ||
f[x] = y, sz[y] += sz[x], nxt[x] = nxt[y] = std::max(nxt[y], nxt[x]); | ||
} | ||
inline void erase(int x) { merge(x, x + 1); } | ||
inline int nxt_lower(int x) { return nxt[getf(x)]; } | ||
inline int nxt_upper(int x) { return nxt[getf(x + 1)]; } | ||
inline bool is_erased(int l, int r) { return nxt[getf(l)] > r; } | ||
inline void cover(int l, int r) { for (l = nxt_lower(l); l <= r; l = nxt_upper(l)) erase(l), --cnt; } | ||
} | ||
int main() | ||
{ | ||
n = cnt = rd(), seg_dsu::init(n); | ||
m = rd(); | ||
while (m--) l = rd(), r = rd(), seg_dsu::cover(l, r), wr(cnt), putchar('\n'); | ||
} |
66 changes: 66 additions & 0 deletions
66
2018级-软件学院-算法分析与设计/E0-算法第0次练习赛-数据结构复习/BUAAOJ2371 序列并查集 路径压缩+启发式合并+非常规分块 O(1).cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <algorithm> | ||
typedef unsigned short u16; | ||
typedef unsigned u32; | ||
#define getchar getchar_unlocked | ||
#define putchar putchar_unlocked | ||
inline int rd() | ||
{ | ||
int k = 0; | ||
char s = getchar(); | ||
while (s < '0' || s > '9') s = getchar(); | ||
while (s >= '0' && s <= '9') k = (k << 1) + (k << 3) + (s ^ '0'), s = getchar(); | ||
return k; | ||
} | ||
inline void wr(int x) | ||
{ | ||
if (x > 9) wr(x / 10); | ||
putchar((x % 10) ^ '0'); | ||
} | ||
const int N = 200100; | ||
int n, m, cnt, l, r; | ||
// worst O(1) 0-index | ||
namespace seg_dsu | ||
{ | ||
const u32 b = 5, B = (1 << b), m = B - 1, M = ~0; | ||
u16 f[N >> b], sz[N >> b], nxt[N >> b]; | ||
u32 val[N >> b]; | ||
inline void init(int n) | ||
{ | ||
for (u16 i = 0; i <= (n >> b); ++i) f[i] = i, sz[i] = 1, nxt[i] = i; | ||
memset(val, 0xff, ((n >> b) + 1) << 2); | ||
} | ||
inline u16 getf(u16 x) { return (f[x] == x) ? x : (f[x] = getf(f[x])); } | ||
inline void merge(u16 x, u16 y) | ||
{ | ||
x = getf(x), y = getf(y); | ||
if (x == y) return; | ||
if (sz[x] > sz[y]) std::swap(x, y); | ||
f[x] = y, sz[y] += sz[x], nxt[x] = nxt[y] = std::max(nxt[y], nxt[x]); | ||
} | ||
inline void join(int x) { val[x >> b] &= (M ^ (1 << (x & m))); } | ||
inline int micro(int x) { return x >> b; } | ||
inline int micro_find(int x) | ||
{ | ||
int pos = x >> b, bit = x & m; | ||
u32 v = val[pos] & (M ^ ((1 << bit) - 1)); | ||
return v ? (pos << b | __builtin_ctz(v)) : ((u32)nxt[getf(pos + 1)]) << b; | ||
} | ||
inline int find(int x) | ||
{ | ||
if (micro(x) ^ micro(micro_find(x))) x = micro_find(micro_find(x)); | ||
while (micro(x) ^ micro(micro_find(x))) | ||
merge(micro(x), micro(micro_find(x))), x = ((u32)nxt[getf(micro(micro_find(x)))]) << b; | ||
return micro_find(x); | ||
} | ||
inline int nxt_lower(int x) { return find(x); } | ||
inline int nxt_upper(int x) { return find(x + 1); } | ||
inline bool is_erased(int l, int r) { return find(l) > r; } | ||
inline void cover(int l, int r) { for (l = nxt_lower(l); l <= r; l = nxt_upper(l)) join(l), --cnt; } | ||
} | ||
int main() | ||
{ | ||
n = cnt = rd(), seg_dsu::init(n), m = rd(); | ||
while (m--) l = rd() - 1, r = rd() - 1, seg_dsu::cover(l, r), wr(cnt), putchar('\n'); | ||
} |