线段树分治题,求助调试
查看原帖
线段树分治题,求助调试
99827
Uzumaki楼主2021/3/13 16:34

错误信息:

Wrong answer on test 11

代码已格式化处理

#include <cstdio>
#include <vector>
#include <algorithm>

const int N = 5e5;
const int K = 50;

int n, m, k, q;

struct Edge
{
  int u, v, Col;
} E[N + 5], Q[N + 5];

int Nxt[N + 5], Lst[N + 5];
std::vector<Edge> S[N * 4 + 5];

int Top;
Edge Sta[N + 5];
struct DSU
{
  int Fa[N + 5], Siz[N + 5], Dis[N + 5], Id;

  void Init(int Col)
  {
    Id = Col;
    for (int i = 1; i <= n; ++i)
    {
      Fa[i] = i;
      Siz[i] = 1;
    }
  }
  bool Merge(int u, int v)
  {
    int Fu = Find(u), Fv = Find(v);
    if (Siz[Fu] > Siz[Fv])
      std::swap(Fu, Fv);
    int Disu = GetDis(u), Disv = GetDis(v);
    if (Fu == Fv)
    {
      if (Disu == Disv)
        return false;
      return true;
    }
    else
    {
      Fa[Fu] = Fv;
      Siz[Fv] += Siz[Fu];
      Dis[Fu] = Disu ^ Disv ^ 1;
      Sta[++Top] = (Edge){Fu, Fv, Id};
      return true;
    }
  }
  void Split(int u, int v)
  {
    Fa[u] = u;
    Dis[u] = 0;
    Siz[v] -= Siz[u];
  }
  int Find(int p)
  {
    if (p == Fa[p])
      return p;
    return Find(Fa[p]);
  }
  int GetDis(int p)
  {
    if (p == Fa[p])
      return 0;
    return Dis[p] ^ GetDis(Fa[p]);
  }
} D[K + 5];

int Ans[N + 5];

void Init();
void Solve(int, int, int);
void Upd(int, int, int, int, int, Edge);

int main()
{
  scanf("%d%d%d%d", &n, &m, &k, &q);
  for (int i = 1; i <= m; ++i)
    scanf("%d%d", &E[i].u, &E[i].v);
  for (int i = 1; i <= q; ++i)
  {
    int e, c;
    scanf("%d%d", &e, &c);
    Q[i] = (Edge){e, 0, c};
  }
  Init();
  Solve(1, 1, q);
  for (int i = 1; i <= q; ++i)
    printf("%s\n", Ans[i] ? "YES" : "NO");
  return 0;
}
void Init()
{
  for (int i = 1; i <= k; ++i)
    D[i].Init(i);
  for (int i = 1; i <= m; ++i)
    Nxt[i] = q + 1;
  for (int i = q; i >= 1; --i)
  {
    Q[i].v = Nxt[Q[i].u] - 1;
    Nxt[Q[i].u] = i;
  }
}
void Upd(int p, int l, int r, int Ql, int Qr, Edge k)
{
  if (Ql <= l && Qr >= r)
    S[p].push_back(k);
  else
  {
    int Mid = (l + r) >> 1;
    if (Ql <= Mid)
      Upd(p << 1, l, Mid, Ql, Qr, k);
    if (Qr > Mid)
      Upd(p << 1 | 1, Mid + 1, r, Ql, Qr, k);
  }
}
void Solve(int p, int l, int r)
{
  int Now = Top;
  for (int i = 0; i < S[p].size(); ++i)
  {
    Edge tap = S[p][i];
    D[tap.Col].Merge(E[tap.u].u, E[tap.u].v);
  }
  if (l >= r)
  {
    Ans[l] = D[Q[l].Col].Merge(E[Q[l].u].u, E[Q[l].u].v);
    if (l < Q[l].v)
    {
      if (Ans[l])
      {
        Upd(1, 1, q, l + 1, Q[l].v, Q[l]);
        Lst[Q[l].u] = l;
      }
      else if (Lst[Q[l].u])
        Upd(1, 1, q, l + 1, Q[l].v, Q[Lst[Q[l].u]]);
    }
  }
  else
  {
    int Mid = (l + r) >> 1;
    Solve(p << 1, l, Mid);
    Solve(p << 1 | 1, Mid + 1, r);
  }
  while (Top > Now)
  {
    D[Sta[Top].Col].Split(Sta[Top].u, Sta[Top].v);
    --Top;
  }
}
2021/3/13 16:34
加载中...