/ SeriousOJ /

Record Detail

Time Exceeded


  
# Status Time Cost Memory Cost
#1 Accepted 2ms 1.27 MiB
#2 Accepted 4ms 1.27 MiB
#3 Time Exceeded ≥2098ms ≥1.484 MiB
#4 Time Exceeded ≥2100ms ≥1.477 MiB

Code

#include <bits/stdc++.h>

#define F first
#define S second
// #define int long long
#define double long double
#define eb emplace_back
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define sz(x) (int)x.size()
#define mp(x, y) make_pair(x, y)
#define lb lower_bound
#define ub upper_bound
#define ins insert
#define INF (int)1e18
using namespace std;

using pii = pair<int, int>;
using pdd = pair<double, double>;
using pbb = pair<bool, bool>;
using pcc = pair<char, char>;
using pss = pair<string, string>;
using vi = vector<int>;
using vd = vector<double>;
using vb = vector<bool>;
using vc = vector<char>;
using vs = vector<string>;
using vpii = vector<pair<int, int>>;
using vpdd = vector<pair<double, double>>;
using vpbb = vector<pair<bool, bool>>;
using vpcc = vector<pair<char, char>>;
using vpss = vector<pair<string, string>>;
using vvi = vector<vector<int>>;
using vvd = vector<vector<double>>;
using vvb = vector<vector<bool>>;
using vvc = vector<vector<char>>;
using vvs = vector<vector<string>>;
using vvpii = vector<vector<pair<int, int>>>;
using vvpdd = vector<vector<pair<double, double>>>;
using vvpbb = vector<vector<pair<bool, bool>>>;
using vvpcc = vector<vector<pair<char, char>>>;
using vvpss = vector<vector<pair<string, string>>>;

// clang-format off
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
template <class T> T sqrt_(T elem) {int l=1,r=elem;while(l<=r){int mid=l+(r-l)/2LL;if(mid>elem/mid){r=mid-1;}else{int val=mid*mid;if(val<=elem){l=mid+1;}else{r=mid-1;}}}return r;}
template <class T> T ceil_(T a,T b) {return(a+b-1)/b;};
template <class T> T mod_add(T a,T b,T mod){return((a%mod)+(b%mod))% mod;}
template <class T> T mod_sub(T a,T b,T mod){return((a%mod)-(b%mod)+mod)%mod;}
template <class T> T mod_mul(T a,T b,T mod){return((a%mod)*(b%mod))%mod;}
template <class T> T mod_inv(T a,T mod){T m0=mod,y=0,x=1;if(mod==1)return 0;while(a>1){T q=a/mod;T t=mod;mod=a%mod,a=t;t=y;y=x-q*y;x=t;}if(x<0)x+=m0;return x;}
template <class T> T mod_div(T a,T b,T mod){return mod_mul(a,mod_inv(b,mod),mod);}
// clang-format on
const int MAXA = 100001;

struct Query {
  int l, r, k, idx;
  bool operator<(const Query& other) const {
    static int block_size = 317;  //
    int block_a = l / block_size;
    int block_b = other.l / block_size;
    if (block_a != block_b) return block_a < block_b;
    return (block_a & 1) ? (r < other.r) : (r > other.r);
  }
};

struct BIT {
  vector<int> bit;
  BIT(int n) : bit(n + 2, 0) {}
  void update(int i, int delta) {
    for (++i; i < bit.size(); i += i & -i) bit[i] += delta;
  }
  int query(int i) {
    int sum = 0;
    for (++i; i > 0; i -= i & -i) sum += bit[i];
    return sum;
  }
  int query(int l, int r) { return query(r) - query(l - 1); }
};

vector<int> answer_queries(const vector<int>& a,
                           const vector<tuple<int, int, int>>& raw_queries) {
  int n = a.size();
  vector<int> a_compressed = a;

  vector<int> sorted = a_compressed;
  sort(sorted.begin(), sorted.end());
  sorted.erase(unique(sorted.begin(), sorted.end()), sorted.end());
  for (int& x : a_compressed)
    x = lower_bound(sorted.begin(), sorted.end(), x) - sorted.begin();

  int m = raw_queries.size();
  vector<Query> queries(m);
  for (int i = 0; i < m; ++i) {
    auto [l, r, k] = raw_queries[i];
    queries[i] = {l, r, k, i};
  }

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

  vector<int> freq(MAXA, 0);
  BIT bit(MAXA);
  vector<int> ans(m);

  int L = 0, R = -1;
  auto add = [&](int pos) {
    int val = a_compressed[pos];
    if (freq[val] == 0) bit.update(val, 1);
    freq[val]++;
  };
  auto remove = [&](int pos) {
    int val = a_compressed[pos];
    freq[val]--;
    if (freq[val] == 0) bit.update(val, -1);
  };

  for (auto& q : queries) {
    while (R < q.r) add(++R);
    while (R > q.r) remove(R--);
    while (L < q.l) remove(L++);
    while (L > q.l) add(--L);

    int k_compressed =
        upper_bound(sorted.begin(), sorted.end(), q.k) - sorted.begin() - 1;
    ans[q.idx] = bit.query(k_compressed);
  }

  return ans;
}
vi sts;
vpii ind;
vvi adj;
int cnt = 0;

void dfs(int node, int par) {
  ind[node].F = cnt;
  ind[node].S = cnt;
  cnt++;

  for (const int& child : adj[node]) {
    if (child != par) {
      dfs(child, node);
      ind[node].S = max(ind[node].S, ind[child].S);
      sts[node] += sts[child];
    }
  }
};

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

  adj = vvi(n);
  ind = vpii(n);
  sts = vi(n, 1);
  cnt = 0;
  vi a(n);

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

  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    adj[u].eb(v);
    adj[v].eb(u);
  }

  dfs(0, -1);

  vi vals(n);

  for (int i = 0; i < n; i++) {
    vals[ind[i].F] = a[i];
  }

  int q;
  cin >> q;
  vi temp(q);

  vector<tuple<int, int, int>> queries(q);
  for (int i = 0; i < q; i++) {
    int x;
    cin >> x;
    x--;
    temp[i] = x;
    int l = ind[x].F, r = ind[x].S, k = sts[x];
    queries[i] = {l, r, k};
  }

  vi ans = answer_queries(vals, queries);
  for (int i = 0; i < q; i++) {
    cout << sts[temp[i]] - ans[i] << '\n';
  }
  return;
}

signed main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

  int tt = 1, count = 1;
  cin >> tt;
  while (tt--) {
    // cout << "Case #" << count << ": ";
    solve();
    ++count;
  }
  return 0;
}

Information

Submit By
Type
Submission
Problem
P1157 Roy and Tree Permutation
Language
C++17 (G++ 13.2.0)
Submit At
2025-06-13 11:21:13
Judged At
2025-06-13 11:21:13
Judged By
Score
10
Total Time
≥2100ms
Peak Memory
≥1.484 MiB