1. 程式人生 > >bzoj 1483 鏈表 + 啟發式合並

bzoj 1483 鏈表 + 啟發式合並

。。 啟發式 d+ his -- insert ins wap 合並

思路:將顏色相同的建成一個鏈表, 變顏色的時候進行鏈表的啟發式合並。。

因為需要將小的接到大的上邊,所以要用個f數組。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>

using namespace std;

const int N = 1e6 + 7;
const int M = 1e5 + 7;
const int inf = 0x3f3f3f3f
; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int n, m, ans, f[N], a[N]; struct node { node(int id, node *nx) { this->id = id; this->nx = nx; } int id; node *nx; } *head[N]; void Insert(int x, int id) { node *p = new node(id, head[x]->nx); head[x]
->nx = p; head[x]->id++; } void Merge(int x, int y) { if(x == y) return; if(head[f[x]]->id > head[f[y]]->id) swap(f[x], f[y]); x = f[x], y = f[y]; node *cur = head[x]; while(cur -> nx != NULL) { cur = cur -> nx; int id = cur->id;
if(a[id - 1] == y) ans--; if(a[id + 1] == y) ans--; } cur = head[x]; while(cur -> nx != NULL) { cur = cur -> nx; int id = cur -> id; a[id] = y; } cur = head[y]; while(cur -> nx != NULL) { cur = cur -> nx; } cur->nx = head[x]->nx; head[y]->id += head[x]->id; head[x]->id = 0; head[x]->nx = NULL; } int main() { for(int i = 1; i <= 1e6; i++) { f[i] = i; head[i] = new node(0, NULL); } scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); if(a[i] != a[i - 1]) ans++; Insert(a[i], i); } while(m--) { int op; scanf("%d", &op); if(op == 1) { int x, y; scanf("%d%d", &x, &y); Merge(x, y); } else { printf("%d\n", ans); } } return 0; } /* */

bzoj 1483 鏈表 + 啟發式合並