QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#263678#7513. Palindromic Beadsucup-team859WA 0ms13360kbC++146.7kb2023-11-25 02:43:162023-11-25 02:43:18

Judging History

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

  • [2024-03-27 16:34:54]
  • hack成功,自动添加数据
  • (/hack/584)
  • [2024-03-27 16:18:45]
  • hack成功,自动添加数据
  • (/hack/583)
  • [2023-11-25 02:43:18]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:13360kb
  • [2023-11-25 02:43:16]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
using namespace chrono;

using ll = long long;
using ull = unsigned long long;

string to_string(const string &s) {
  return '"' + s + '"';
}

string to_string(bool b) {
  return b ? "true" : "false";
}

template <typename A, typename B>
string to_string(const pair<A, B> &p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename T>
string to_string(const T &v) {
  string s = "{";
  bool first = true;
  for (const auto &it : v) {
    if (!first)
      s += ", ";
    else
      first = false;
    s += to_string(it);
  }
  return s += "}";
}

void debug_out() {
  cerr << endl;
}

template <typename T, typename... Args>
void debug_out(const T &first, const Args&... rest) {
  cerr << to_string(first) << " ";
  debug_out(rest...);
}

#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

auto startTime = high_resolution_clock::now();
int get_time() {
  auto stopTime = chrono::high_resolution_clock::now();
  auto duration = duration_cast<milliseconds>(stopTime - startTime);
  return duration.count(); // in ms
}

namespace segtree2d {
  // dynamic segtree2d with point update and rectangle query
  
  struct node {
    int l, r;
    int d; // value for ox->oy node or actual value
  };

  int n, m;
  vector<node> arb;

  void build(int _n, int _m, int q) {
    n = _n;
    m = _m;
    if (q == 0)
      q = 1;
    arb.reserve(q);
  }

  inline void calculate(int nod) {
    if (arb[nod].l != 0)
      arb[nod].d = max(arb[nod].d, arb[arb[nod].l].d);
    if (arb[nod].r != 0)
      arb[nod].d = max(arb[nod].d, arb[arb[nod].r].d);
  }

  void update_y(int x, int y, int v, int nod, int st = 1, int dr = m) {
    if (st == dr) {
      arb[nod].d = v;
      return;
    }

    int mij = (st + dr) / 2;
    if (x <= mij) {
      if (arb[nod].l == 0) {
        arb[nod].l = arb.size();
        arb.emplace_back();
      }
      update_y(x, y, v, arb[nod].l, st, mij);
    } else { 
      if (arb[nod].r == 0) {
        arb[nod].r = arb.size();
        arb.emplace_back();
      }
      update_y(x, y, v, arb[nod].r, mij + 1, dr);
    }   

    calculate(nod);
  }

  void update_x(int x, int y, int v, int nod = 0, int st = 1, int dr = n) {
    if (arb[nod].d == 0) {
      arb[nod].d = arb.size();
      arb.emplace_back();
    }

    update_y(x, y, v, arb[nod].d);

    if (st == dr)
      return;

    int mij = (st + dr) / 2;
    if (x <= mij) {
      if (arb[nod].l == 0) {
        arb[nod].l = arb.size();
        arb.emplace_back();
      }
      update_x(x, y, v, arb[nod].l, st, mij);
    } else {
      if (arb[nod].r == 0) {
        arb[nod].r = arb.size();
        arb.emplace_back();
      }
      update_x(x, y, v, arb[nod].r, mij + 1, dr);
    }
  }

  int query_y(int x, int y, int nod, int st = 1, int dr = m) {
    if (nod == 0)
      return 0;

    if (x <= st && dr <= y)
      return arb[nod].d;

    int mij = (st + dr) / 2;
    if (x <= mij && mij + 1 <= y)
      return max(query_y(x, y, arb[nod].l, st, mij), query_y(x, y, arb[nod].r, mij + 1, dr));

    if (x <= mij)
      return query_y(x, y, arb[nod].l, st, mij);

    return query_y(x, y, arb[nod].r, mij + 1, dr);
  }

  int query_x(int x, int y, int x2, int y2, int nod = 0, int st = 1, int dr = m) {
    if (x <= st && dr <= y)
      return query_y(x2, y2, arb[nod].d); 

    int mij = (st + dr) / 2;
    if (x <= mij && mij + 1 <= y && arb[nod].l != 0 && arb[nod].r != 0)
      return max(query_x(x, y, x2, y2, arb[nod].l, st, mij), query_x(x, y, x2, y2, arb[nod].r, mij + 1, dr));

    if (x <= mij && arb[nod].l != 0)
      return query_x(x, y, x2, y2, arb[nod].l, st, mij);

    if (arb[nod].r != 0)
      return query_x(x, y, x2, y2, arb[nod].r, mij + 1, dr);

    return 0;
  }
}

const int DIM = 2e5 + 5;

int a[DIM], h[DIM];
int f[DIM], nr[DIM];
int tmp, l[DIM], r[DIM];
int tt[DIM][20];
vector<int> v[DIM];

int get_dist(int x, int y) {
  if (h[x] < h[y])
    swap(x, y);

  int df = h[x] - h[y];
  int le = 0;
  for (int k = 19; k >= 0 ; --k) {
    if ((1 << k) & df) {
      x = tt[x][k];
      le |= 1 << k;
    }
  }
  if (x == y)
    return le;

  for (int k = 19; k >= 0 ; --k) {
    if (tt[x][k] != tt[y][k]) {
      x = tt[x][k];
      y = tt[y][k];
      le += 1 << k;
    }
  }

  return le;
}

int is_ancestor(int x, int y) {
  if (x == y)
    return x;

  if (h[x] < h[y])
    swap(x, y);

  int df = h[x] - h[y] - 1;
  for (int k = 19; k >= 0 ; --k)
    if ((1 << k) & df)
      x = tt[x][k];

  if (tt[x][0] == y)
    return x;

  return -1; 
}

void dfs(int nod = 1) {
  f[a[nod]] = nod;
  l[nod] = ++tmp;
  for (auto it : v[nod]) {
    if (it == tt[nod][0])
      continue;
    h[it] = h[nod] + 1;
    tt[it][0] = nod;
    dfs(it);
  }
  r[nod] = tmp;
}

struct pairs {
  int x, y, d;
  bool operator < (const pairs &aux) const {
    return d > aux.d; 
  }
};

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

  for (int i = 1; i <= n; ++i) {
    cin >> a[i];
    ++nr[a[i]];
  }

  for (int i = 1; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    v[x].push_back(y);
    v[y].push_back(x);
  }

  tmp = 0;
  dfs();
  for (int k = 1; k <= 19; ++k) {
    for (int i = 1; i <= n; ++i)
      tt[i][k] = tt[tt[i][k - 1]][k - 1];
  }

  vector<pairs> v;
  for (int i = 1; i <= n; ++i) {
    if (f[a[i]] != i) {
      int x = i;
      int y = f[a[i]];
      if (h[x] < h[y])
        swap(x, y);
      
      int d = get_dist(x, y);
      v.push_back({x, y, d});
    }
  }

  sort(v.begin(), v.end());

  int ans = 1;
  segtree2d::build(n, n, n);
  for (auto it : v) {
    int nod = is_ancestor(it.x, it.y);
    int q;
    if (nod == -1) {
      q = segtree2d::query_x(l[it.x], r[it.x], l[it.y], r[it.y]);
    } else {
      q = segtree2d::query_x(1, l[nod] - 1, l[it.x], r[it.x]);
      q = max(q, segtree2d::query_x(r[nod] + 1, n, l[it.x], r[it.x]));
    }

    ans = max(ans, q + 2);
    segtree2d::update_x(l[it.x], l[it.y], q + 2);
    segtree2d::update_x(l[it.y], l[it.x], q + 2);
  }

  for (int i = 1; i <= n; ++i) {
    if (l[i] > 1 && l[i] + 1 <= r[i])
      ans = max(ans, segtree2d::query_x(1, l[i] - 1, l[i] + 1, r[i]) + 1);

    if (l[i] + 1 <= r[i] && r[i] + 1 <= n)
      ans = max(ans, segtree2d::query_x(r[i] + 1, n, l[i] + 1, r[i]) + 1);
  }

  cout << ans << '\n';
}

int main() {
  cin.tie(NULL);
  ios_base::sync_with_stdio(false);

  int t = 1;
//  cin >> t;
  while (t--)
    solve();

  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 0ms
memory: 13360kb

input:

4
1 1 2 2
1 2
2 3
2 4

output:

2

result:

wrong answer 1st lines differ - expected: '3', found: '2'