1. 程式人生 > >[HNOI 2009] 夢幻布丁

[HNOI 2009] 夢幻布丁

include span digi 啟發式 hnoi 2009 div print template owa

[題目鏈接]

https://www.lydsy.com/JudgeOnline/problem.php?id=1483

[算法]

鏈表 + 啟發式合並即可

時間復雜度 : O(NlogN)

[代碼]

#include<bits/stdc++.h>
using namespace std;
#define N 1000010
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

int n , m , nowans;
int nxt[N] , head[N] , sz[N] , w[N] , f[N];

template 
<typename T> inline void chkmin(T &x , T y) { x = min(x , y); } template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c ==
-) f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - 0; x *= f; } inline void merge(int x , int y) { for (int i = head[x]; i; i = nxt[i]) nowans -= (w[i - 1] == y) + (w[i + 1] == y); for (int i = head[x]; i; i = nxt[i]) w[i] = y; int tail = 0;
for (int i = head[x]; i; i = nxt[i]) tail = i; nxt[tail] = head[y] , head[y] = head[x]; sz[y] += sz[x]; head[x] = 0 , sz[x] = 0; } int main() { read(n); read(m); for (int i = 1; i <= n; i++) read(w[i]); nowans = unique(w + 1 , w + n + 1) - w - 1; for (int i = 1; i <= nowans; i++) { nxt[i] = head[w[i]]; head[w[i]] = i; ++sz[w[i]]; f[w[i]] = w[i]; } for (int i = 1; i <= m; i++) { int type; read(type); if (type == 1) { int x , y; read(x); read(y); if (x == y) continue; if (sz[f[x]] > sz[f[y]]) swap(f[x] , f[y]); if (!sz[f[x]]) continue; merge(f[x] , f[y]); } else printf("%d\n" , nowans); } return 0; }

[HNOI 2009] 夢幻布丁