蒟蒻求调。玄学segmentfault,过不了样例
查看原帖
蒟蒻求调。玄学segmentfault,过不了样例
731709
georgeyu123楼主2022/8/9 11:11
// template
#include <bits/stdc++.h>
using namespace std;
#define debug puts(" <-- TO BE CONTINUE -->")
typedef long long ll;
namespace IO {
template <typename _Tp>
inline void read(_Tp& x) {
  register char ch = getchar();
  register int f = 1;
  x = 0;
  for (; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = (x << 3) + (x << 1) + (ch ^ 48);
  x *= f;
}
template <typename _Tp>
inline void write(_Tp x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) write(x / 10);
  putchar(x % 10 ^ 48);
}
template <typename _Tp>
inline void writec(_Tp x, char c) {
  write(x), putchar(c);
}
}  // namespace IO
using namespace IO;
#define N 4000005
int n, m, rt, mod;
int cnt = 0;
int a[N];
class edge {
 public:
  int v, nxt;
} E[N];
int head[N];
inline void add_edge(int u, int v) {
  E[++cnt] = (edge){v, head[u]}, head[u] = cnt;
}
int dep[N], fa[N], sz[N], ch[N];
inline void dfs1(int index, int __dep) {
  dep[index] = __dep;
  sz[index] = 1;
  for (int i = head[index]; i; i = E[i].nxt) {
    int y = E[i].v;
    if (fa[index] == y) continue;
    fa[y] = index;
    dfs1(y, __dep + 1);
    sz[index] += sz[y];
    if (sz[y] > sz[ch[index]]) ch[index] = y;
  }
}
int top[N], dfn[N], lst[N], tot = 0;
inline void dfs2(int index, int __top) {
  top[index] = __top;
  dfn[index] = ++tot;
  lst[tot] = a[index];
  if (ch[index] == 0) return;
  dfs2(ch[index], __top);
  for (int i = head[index]; i; i = E[i].nxt) {
    int y = E[i].v;
    if (y == ch[index] || y == fa[index])
      continue;
    else
      dfs2(y, y);
  }
}
class Seginfo {
 public:
  int l, r;
  int lt, data;
} seg[N << 2];
#define lson index << 1
#define rson index << 1 | 1
inline void pushup(int index) {
  seg[index].data = (seg[lson].data + seg[rson].data) % mod;
}
/*
inline void mark(int index, int l, int r, int k) {
  seg[index].data += k * (r - l + 1);
  seg[index].lt += k;
  return;
}
*/
inline void pushdown(int index) {
  if (seg[index].lt != 0) {
    // int mid = seg[index].l + seg[index].r >> 1;
    // mark(lson, seg[index].l, mid, seg[index].lt);
    // mark(rson, mid + 1, seg[index].r, seg[index].lt);
    seg[lson].lt = (seg[lson].lt + seg[index].lt) % mod;
    seg[rson].lt = (seg[rson].lt + seg[index].lt) % mod;
    (seg[lson].data += seg[index].lt * (seg[lson].r - seg[lson].l + 1)) %= mod;
    (seg[rson].data += seg[index].lt * (seg[rson].r - seg[rson].l + 1)) %= mod;
    seg[index].lt = 0;
  }
}
inline void build(int index, int l, int r) {
  seg[index].l = l, seg[index].r = r, seg[index].lt = 0;
  if (l == r) {
    seg[index].data = lst[l] % mod;
    return;
  }
  int mid = l + r >> 1;
  build(lson, l, mid), build(rson, mid + 1, r);
  pushup(index);
}
inline void change(int index, int l, int r, int k) {
  if (l <= seg[index].l && r >= seg[index].r) {
    seg[index].data =
        (seg[index].data + k * (seg[index].r - seg[index].l + 1)) % mod;
    seg[index].lt = (seg[index].lt + k) % mod;
    return;
  }
  pushdown(index);
  int mid = seg[index].l + seg[index].r >> 1;
  if (l <= mid) change(lson, l, mid, k);
  if (r > mid) change(rson, mid + 1, r, k);
  pushup(index);
}
inline int query(int index, int l, int r) {
  int ret = 0;
  if (l <= seg[index].l && seg[index].r <= r) {
    seg[index].data %= mod;
    return seg[index].data;
  }
  pushdown(index);
  int mid = l + r >> 1;
  if (l <= mid) ret = (query(lson, l, r) + ret) % mod;
  if (r > mid) ret = (query(rson, l, r) + ret) % mod;
  return ret % mod;
}
inline void RangeAdd(int u, int v, int k) {
  //  debug;
  while (top[u] != top[v]) {
    //    debug;
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    //    debug;
    change(1, dfn[top[u]], dfn[u], k);
    //    debug;
    u = fa[top[u]];
  }
  //  debug;
  if (dep[u] > dep[v]) swap(u, v);
  change(1, dfn[u], dfn[v], k);
}
inline int RangeCount(int u, int v) {
  int ret = 0;
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    ret = (query(1, dfn[top[u]], dfn[u])) % mod;
    u = fa[top[u]];
  }
  if (dep[u] > dep[v]) swap(u, v);
  ret = (ret + query(1, dfn[u], dfn[v])) % mod;
  return ret;
}
inline void TreeAdd(int index, int k) {
  change(1, dfn[index], dfn[index] + sz[index] - 1, k);
}
inline int TreeCount(int index) {
  int ret = 0;
  ret = query(1, dfn[index], dfn[index] + sz[index] - 1) % mod;
  return ret;
}

signed main() {
  // freopen("sp.in", "r", stdin);
  //  freopen("sp.out", "w", stdout);
  //  debug;
  read(n), read(m), read(rt), read(mod);
  for (int i = 1; i <= n; ++i) read(a[i]), a[i] %= mod;
  //  debug;
  for (int i = 1, x, y; i < n; ++i)
    read(x), read(y), add_edge(x, y), add_edge(y, x);
  //  debug;
  dfs1(rt, 1), dfs2(rt, rt);
  build(1, 1, n);
  /*
        for (int i = 1; i <= n; ++i) {
    printf(
        "i = %d, dep = %d, fa = %d, ch = %d, sz = %d, top = %d, dfn = %d, lst "
        "= %d\n",
        i, dep[i], fa[i], ch[i], sz[i], top[i], dfn[i], lst[i]);
  }
  */
  for (int i = 1; i <= m; ++i) {
    int opt, x, y, z;
    read(opt);
    if (opt == 1)
      debug, read(x), read(y), read(z), debug, RangeAdd(x, y, z % mod);
    else if (opt == 2)
      read(x), read(y), writec(RangeCount(x, y), '\n');
    else if (opt == 3)
      read(x), read(z), TreeAdd(x, z);
    else if (opt == 4)
      read(x), writec(TreeCount(x), '\n');
    //    cout << "CASE #" << i << ": " << debug;
  }
  return 0;
}
/*
5 5 2 24
7 3 7 8 0
1 2
1 5
3 1
4 1
3 4 2
3 2 2
4 5
1 5 1 3
2 1 3
*/
2022/8/9 11:11
加载中...