QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#837593#9772. Permutation Routingnhuang685TL 0ms3528kbC++235.5kb2024-12-30 08:52:082024-12-30 08:52:09

Judging History

你现在查看的是最新测评结果

  • [2025-01-10 11:38:24]
  • hack成功,自动添加数据
  • (/hack/1438)
  • [2024-12-30 08:52:09]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:3528kb
  • [2024-12-30 08:52:08]
  • 提交

answer

/**
 * @author n685
 * @date 2024-12-29 16:25:30
 */
#include "bits/stdc++.h"

#ifdef LOCAL
#include "dd/debug.h"
#else
#define dbg(...) 42
#define dbg_proj(...) 420
#define dbg_rproj(...) 420420
void nline() {}
void bar() {}
void start_clock() {}
void end_clock() {}
#endif

namespace rs = std::ranges;
namespace rv = std::views;

using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;

void solve() {
  int n;
  std::cin >> n;

  std::vector<int> p(n);
  for (int& v : p) {
    std::cin >> v;
    --v;
  }

  std::vector<std::vector<std::pair<int, int>>> adj(n);
  std::vector<std::pair<int, int>> edges;
  for (int i = 0; i < n - 1; ++i) {
    int u, v;
    std::cin >> u >> v;
    --u;
    --v;
    adj[u].emplace_back(i, v);
    adj[v].emplace_back(i, u);
    edges.emplace_back(u, v);
  }
  auto sep = [&](int i, int j) {
    return edges[i].first != edges[j].first && edges[i].first != edges[j].second
      && edges[i].second != edges[j].first
      && edges[i].second != edges[j].second;    
  };

  std::vector<std::vector<int>> ans;
  auto apply = [&](std::vector<int> v) {
    if (v.empty()) {
      return;
    }
    rs::sort(v);
    v.erase(rs::unique(v).begin(), v.end());
    if (ans.empty()) {
      for (int i : v) {
        std::swap(p[edges[i].first], p[edges[i].second]);
      }
      ans.push_back(v);
      return;
    }
    ans.emplace_back();
    for (int i : v) {
      std::swap(p[edges[i].first], p[edges[i].second]);
      bool g = true;
      for (int j : ans.end()[-2]) {
        if (!sep(i, j)) {
          g = false;
          break;
        }
      }
      if (g) {
        ans.end()[-2].push_back(i);
      } else {
        ans.back().push_back(i);
      }
    }
    if (ans.back().empty()) {
      ans.pop_back();
    } else if (ans.end()[-2] == ans.back()) {
      ans.pop_back();
      ans.pop_back();
    }
  };

  std::vector<int> sub(n), rem(n);
  auto comp_sub = [&](auto&& self, int node, int par) -> void {
    sub[node] = 1;
    for (auto [t, i] : adj[node]) {
      if (i == par || rem[i]) {
        continue;
      }
      self(self, i, node);
      sub[node] += sub[i];
    }
  };
  auto cent = [&](auto&& self, int node, int par, int sz) -> int {
    for (auto [t, i] : adj[node]) {
      if (i == par || rem[i]) {
        continue;
      }
      if (2 * sub[i] > sz) {
        return self(self, i, node, sz);
      }
    }
    return node;
  };

  std::vector<int> bel(n);
  auto comp_bel_dfs = [&](auto&& self, int node, int par, int val) -> void {
    bel[node] = val;
    for (auto [t, i] : adj[node]) {
      if (i != par && !rem[i]) {
        self(self, i, node, val);
      }
    }
  };
  auto comp_bel = [&](int rt) -> void {
    bel[rt] = -1;
    for (auto [t, i] : adj[rt]) {
      if (!rem[i]) {
        comp_bel_dfs(comp_bel_dfs, i, rt, t);
      }
    }
  };
  auto good = [&](int node) -> bool { return bel[node] == bel[p[node]]; };
  auto phase1_dfs =
    [&](auto&& self, int node, int par, std::vector<int>& fl, bool cc) -> void {
    bool g = cc && (good(node) || bel[p[node]] == -1);
    for (auto [t, i] : adj[node]) {
      if (i == par || rem[i]) {
        continue;
      }
      bool ch = true;
      if (g && !good(i)) {
        ch = false;
        fl.push_back(t);
        g = false;
      }
      self(self, i, node, fl, ch);
    }
  };
  auto phase1 = [&](int rt, std::vector<int>& fl) -> void {
    for (auto [t, i] : adj[rt]) {
      if (!rem[i]) {
        phase1_dfs(phase1_dfs, i, rt, fl, true);
      }
    }
  };

  auto gen = [&](auto&& self, int rt) -> void {
    comp_sub(comp_sub, rt, -1);
    rt = cent(cent, rt, -1, sub[rt]);
    dbg(rt);
    comp_bel(rt);
    // while (true) {
    //   std::vector<int> fl;
    //   phase1(rt, fl);
    //   if (fl.empty()) {
    //     break;
    //   }
    //   apply(fl);
    // }
    while (true) {
      std::vector<int> fl1;
      for (auto [t, i] : adj[rt]) {
        if (p[i] != i && !rem[i] && !good(i)) {
          fl1.push_back(t);
          break;
        }
      }
      if (fl1.empty()) {
        for (auto [t, i] : adj[rt]) {
          if (!rem[i] && !good(i)) {
            fl1.push_back(t);
            break;
          }
        }
        if (fl1.empty()) {
          break;
        }
      }
      bool ep = fl1.empty();
      for (auto [t, i] : adj[rt]) {
        if (!rem[i]) {
          phase1_dfs(phase1_dfs, i, rt, fl1, ep || fl1[0] != t);
        }
      }
      apply(fl1);
      std::vector<int> fl2;
      for (auto [t, i] : adj[rt]) {
        if (!rem[i] && bel[p[rt]] == t) {
          fl2.push_back(t);
          break;
        }
      }
      // phase1(rt, fl2);
      ep = fl2.empty();
      for (auto [t, i] : adj[rt]) {
        if (!rem[i]) {
          phase1_dfs(phase1_dfs, i, rt, fl2, ep || fl2[0] != t);
        }
      }
      if (!fl2.empty()) {
        apply(fl2);
      }
    }
    rem[rt] = true;
    for (auto [t, i] : adj[rt]) {
      if (!rem[i]) {
        self(self, i);
      }
    }
  };
  gen(gen, 0);
  std::cout << ans.size() << '\n';
  for (const auto& v : ans) {
    std::cout << v.size();
    for (int i : v) {
      std::cout << ' ' << i + 1;
    }
    std::cout << '\n';
  }
}

int main() {
#ifndef LOCAL
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
#endif

  int t;
  std::cin >> t;
  for (int i = 0; i < t; ++i) {
    dbg(i + 1);
    solve();
    bar();
  }
}


详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3528kb

input:

1
5
1 4 2 5 3
1 2
2 3
2 4
1 5

output:

6
2 2 4
1 1
1 2
1 3
1 1
1 4

result:

ok ok, up to 6 steps were used

Test #2:

score: -100
Time Limit Exceeded

input:

10000
5
2 3 1 5 4
1 5
3 2
1 2
1 4
5
1 2 3 4 5
2 3
3 4
2 1
4 5
5
4 2 5 1 3
3 5
2 3
4 1
3 1
5
1 3 4 2 5
5 3
2 1
1 3
2 4
5
1 2 3 4 5
2 1
3 5
2 3
5 4
5
1 2 3 4 5
4 5
3 4
4 2
4 1
5
5 2 1 4 3
2 1
5 1
3 1
1 4
5
4 1 2 5 3
3 1
5 1
1 2
1 4
5
5 3 4 2 1
3 1
3 5
4 3
3 2
5
3 4 1 2 5
3 2
3 5
1 5
3 4
5
3 4 1 2 5
2 ...

output:


result: