BZOJ 1483 梦幻布丁

拈花ヽ惹草 提交于 2019-11-30 19:48:31

题意:

给你序列上的初始颜色,每次把一个颜色全部改成另外一个颜色

$n \leq 10^5, color \leq 10^6, m \leq 10^6$

sol:

这题卡了一个星期,其实还是还是中间出的锅太多。

链表启发式合并即可。

注意的点:

1 : 注意在交换之后再判断$head$,因为可能交换了。

2 : 注意清空$siz$,这关系到启发式合并的正确性

3 : 注意交换的是$F[x]和F[y]$而不是$rx,ry$的$F$

#include<cstdio>
#include<iostream>
#define debug printf("GG\n")
const int N = 1e6+7;
int head[N], nxt[N], siz[N], col[N], pre[N], last[N];
int n, m, F[N], ans;
void Modify(int x, int y) {
  // x -> y
  for (int o = head[x]; o; o = nxt[o]) {
    // col[o] = y;
    ans -= (col[o - 1] == y) + (col[o + 1] == y);
  }
  for (int o = head[x]; o; o = nxt[o])
    col[o] = y;
  nxt[last[y]] = head[x], pre[head[x]] = last[y], head[x] = 0;
  last[y] = last[x], last[x] = 0, siz[y] += siz[x], siz[x] = 0; // 别忘了清空x 这里挂了 
  // Debug;
}
int main() {
  //freopen("2.in", "r", stdin);
  //freopen("22.out", "w", stdout);
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= 1e6;F[i] = i, i++);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &col[i]);
    if (!head[col[i]]) head[col[i]] = last[col[i]] = i;
    else nxt[last[col[i]]] = i, pre[i] = last[col[i]], last[col[i]] = i;
    if (col[i] != col[i - 1]) ans++;
    siz[col[i]]++; 
  }
  for (int i = 1; i <= m; i++) {
    int opt, x, y;
    scanf("%d", &opt);
    if (opt == 2) {
      printf("%d\n", ans);
      continue;
    } else if (opt == 1) {
      scanf("%d%d", &x, &y);
      int rx = F[x], ry = F[y];
      //if (!siz[F[x]] || rx == ry) {
        //debug;
      //  continue;
     // }
      if (siz[rx] > siz[ry])
        std ::swap(F[x], F[y]), std :: swap(rx, ry);//注意交换的是F[x]和F[y]而不是  
      if (!head[rx] || rx == ry) continue; // 判断head为空要在后面判,因为改的x可能交换了 
      Modify(rx, ry);
    } else if (opt == 3) {
      for (int i = 1; i <= n; i++)
        printf("F[%d] -> %d\n", i, F[i]);
    } else if (opt == 4) {
      for (int i = 1; i <= n; i++)
        printf("%d ", col[i]);
    } else if (opt == 5) {
      scanf("%d", &x);
      printf("%d\n", head[x]);
    }
  } return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!