[HNOI 2009] 夢幻布丁
阿新 • • 發佈:2019-02-14
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] 夢幻布丁