QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#872253#8616. Fast Tree Queriesucup-team008#RE 0ms9452kbC++175.1kb2025-01-26 00:14:192025-01-26 00:14:25

Judging History

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

  • [2025-01-26 00:14:25]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:9452kb
  • [2025-01-26 00:14:19]
  • 提交

answer

#include <algorithm>
#include <array>
#include <iostream>
#include <vector>

#pragma GCC target("avx2")
#pragma GCC optimize("O3")

using namespace std;

// BEGIN NO SAD
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound
typedef vector<int> vi;
#define f first
#define s second
#define derr if(1) cerr

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}
 
template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ", "; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? ", " : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#define debug(x...) cerr << "\e[91m"<<__func__<<":"<<__LINE__<<" [" << #x << "] = ["; _print(x); cerr << "\e[39m" << flush;
// END NO SAD

template<class T>
bool updmin(T& a, T b) {
  if(b < a) {
    a = b;
    return true;
  }
  return false;
}
template<class T>
bool updmax(T& a, T b) {
  if(b > a) {
    a = b;
    return true;
  }
  return false;
}
typedef int64_t ll;

void inc(int* a, int len, int delta) {
  for(int i = 0; i < len; i++) a[i] += delta;
}
int qry(int* a, int len) {
  int ret = 0;
  for(int i = 0; i < len; i++) ret ^= a[i];
  return ret;
}

const int MAXN = 100005;
int to[2*MAXN];
int nextID[2*MAXN];
int start[MAXN];
int treedepth[MAXN];
int treesz[MAXN];
int treepar[MAXN];
int treetop[MAXN]; // treetop[v] -> top of chain
int treechainidx[MAXN]; // top of chain = 0, next of chain = 1
vector<int> paths[MAXN];

void pathinc(int a, int b, int delta) {
  while(treetop[a] != treetop[b]) {
    if(treedepth[treetop[a]] > treedepth[treetop[b]]) swap(a, b);
    int amt = treedepth[b] - treedepth[treetop[b]] + 1;
    inc(paths[treetop[b]].data(), amt, delta);
    b = treepar[treetop[b]];
  }
  if(treedepth[a] > treedepth[b]) {
    swap(a, b);
  }
  int amt = treedepth[b] - treedepth[a];
  inc(paths[treetop[a]].data() + treedepth[a], amt+1, delta);
}
int pathqry(int a, int b) {
  int ret = 0;
  while(treetop[a] != treetop[b]) {
    if(treedepth[treetop[a]] > treedepth[treetop[b]]) swap(a, b);
    int amt = treedepth[b] - treedepth[treetop[b]] + 1;
    ret ^= qry(paths[treetop[b]].data(), amt);
    b = treepar[treetop[b]];
  }
  if(treedepth[a] > treedepth[b]) {
    swap(a, b);
  }
  int amt = treedepth[b] - treedepth[a];
  ret ^= qry(paths[treetop[a]].data() + treedepth[a], amt+1);
  return ret;
}

void dfs(int curr, int par) {
  treesz[curr] = 1;
  for(int id = start[curr]; id != -1; id = nextID[id]) {
    int out = to[id];
    if(out != par) {
      treedepth[out] = treedepth[curr] + 1;
      treepar[out] = curr;
      dfs(out, curr);
      treesz[curr] += treesz[out];
    }
  }
}
void dfsforhld(int curr, int top, int cidx, int par) {
  paths[top].pb(curr+1);
  treetop[curr] = top;
  treechainidx[curr] = cidx;
  int bigchild = -1;
  for(int id = start[curr]; id != -1; id = nextID[id]) {
    int cand = to[id];
    if(cand == par) continue;
    if(bigchild == -1 || treesz[cand] > treesz[bigchild]) bigchild = cand;
  }
  for(int id = start[curr]; id != -1; id = nextID[id]) {
    int cand = to[id];
    if(cand == par) continue;
    if(cand == bigchild) dfsforhld(cand, top, cidx+1, curr);
    else dfsforhld(cand, cand, 0, curr);
  }
}
void solve() {
  int n, q;
  cin >> n >> q;
  for(int i = 0; i < n; i++) start[i] = -1;
  for(int i = 0; i < n-1; i++) {
    int a, b;
    cin >> a >> b;
    a--; b--;
    to[2*i] = b;
    nextID[2*i] = start[a];
    start[a] = 2*i;
    to[2*i+1] = a;
    nextID[2*i+1] = start[b];
    start[b] = 2*i+1;
  }
  dfs(0, -1);
  dfsforhld(0, 0, 0, -1);
  while(q--) {
    char op;
    cin >> op;
    if(op == '?') {
      int a, v;
      cin >> a >> v;
      a--; v--;
      cout << pathqry(a, v) << "\n";
    }
    else {
      int a, v, x;
      cin >> a >> v >> x;
      a--; v--;
      pathinc(a, v, x);
    }
  }
}

// what would chika do
// are there edge cases (N=1?)
// are array sizes proper (scaled by proper constant, for example 2* for koosaga tree)
// integer overflow?
// DS reset properly between test cases
// are you doing geometry in floating points

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

詳細信息

Test #1:

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

input:

5 6
1 2
1 3
3 4
3 5
? 2 5
+ 1 4 1
? 2 5
+ 4 5 2
? 4 5
? 1 1

output:

5
1
6
2

result:

ok 4 number(s): "5 1 6 2"

Test #2:

score: -100
Runtime Error

input:

100 100
6 74
6 93
7 46
7 78
10 77
11 9
11 19
11 37
11 51
11 65
12 57
13 15
13 81
13 100
14 2
14 31
16 11
16 24
16 43
16 82
18 4
18 8
21 56
24 29
24 96
26 22
27 32
28 59
29 6
29 94
32 33
35 54
35 80
35 88
37 66
37 71
37 84
38 17
39 64
39 92
40 49
43 7
43 13
43 44
43 79
44 35
44 60
44 63
44 73
46 75
4...

output:


result: