题目测试链接

代码

/*
  Author : lifehappy
*/
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define endl '\n'
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const double pi = acos(-1.0);
const double eps = 1e-7;
const int inf = 0x3f3f3f3f;

inline ll read() {
  ll f = 1, x = 0;
  char c = getchar();
  while(c < '0' || c > '9') {
    if(c == '-')    f = -1;
    c = getchar();
  }
  while(c >= '0' && c <= '9') {
    x = (x << 1) + (x << 3) + (c ^ 48);
    c = getchar();
  }
  return f * x;
}

void print(ll x) {
  if(x < 10) {
    putchar(x + 48);
    return ;
  }
  print(x / 10);
  putchar(x % 10 + 48);
}

const int N = 1e5 + 10, mod = 23333;

ll res[N << 2], sum[N << 2], lazy[N << 2];//线段树数组。
ll value[N];
int head[N], to[N << 1], nex[N << 1], cnt = 1;
int n, m, dfn[N], sz[N], tot, st[N];

void add(int x, int y) {
  to[cnt] = y;
  nex[cnt] = head[x];
  head[x] = cnt++;
}

void dfs(int rt, int fa) {
  dfn[++tot] = rt;
  st[rt] = tot;
  sz[rt] = 1;
  for(int i = head[rt]; i; i = nex[i]) {
    if(to[i] == fa) continue;
    dfs(to[i], rt);
    sz[rt] += sz[to[i]];
  }
}

void push_up(int rt) {
  res[rt] = (res[ls] + res[rs]) % mod;
  sum[rt] = (sum[ls] + sum[rs]) % mod;
}

void build_tree(int rt, int l, int r) {
  if(l == r) {
    sum[rt] = value[dfn[l]] % mod;
    res[rt] = (sum[rt] * sum[rt]) % mod;
    return ;
  }
  build_tree(lson);
  build_tree(rson);
  push_up(rt);
}

void push_down(int rt, int l, int r) {
  if(lazy[rt]) {
    lazy[ls] += lazy[rt], lazy[rs] += lazy[rt];
    res[ls] = (res[ls] + (((lazy[rt] * lazy[rt]) % mod) * (mid - l + 1)) % mod + (2ll * sum[ls] * lazy[rt]) % mod) % mod;
    res[rs] = (res[rs] + (((lazy[rt] * lazy[rt]) % mod) * (r - mid)) % mod + (2ll * sum[rs] * lazy[rt]) % mod) % mod;
    sum[ls] = (sum[ls] + (mid - l + 1) * lazy[rt]) % mod;
    sum[rs] = (sum[rs] + (r - mid) * lazy[rt]) % mod;
    lazy[rt] = 0;
  }
}

void update(int rt, int l, int r, int L, int R, ll k) {
  if(l >= L && r <= R) {
    lazy[rt] += k;
    res[rt] = (res[rt] + (((k * k) % mod) * (r - l + 1)) % mod + (2ll * sum[rt] * k) % mod) % mod;
    sum[rt] = (sum[rt] + (r - l + 1) * k) % mod;
    return ;
  }
  push_down(rt, l, r);
  if(L <= mid) update(lson, L, R, k);
  if(R > mid)  update(rson, L, R, k);
  push_up(rt);
}

ll query(int rt, int l, int r, int L, int R){
  if(l >= L && r <= R)  return res[rt];
  push_down(rt, l, r);
  ll ans = 0;
  if(L <= mid) ans += query(lson, L, R);
  if(R > mid)  ans += query(rson, L, R);
  return ans;
}

int main() {
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  n = read(), m = read();
  for(int i = 1; i <= n; i++) value[i] = read();
  for(int i = 1; i < n; i++) {
    int x = read(), y = read();
    add(x, y);
    add(y, x);
  }
  dfs(1, 0);
  build_tree(1, 1, n);
  for(int i = 1; i <= m; i++) {
    int op = read();
    if(op == 1) {
      int x = read(), y = read();
      update(1, 1, n, st[x],st[x] + sz[x] - 1, y % mod);
    }
    else {
      int x = read();
      printf("%lld\n", query(1, 1, n, st[x],st[x] + sz[x] - 1) % mod);
    }
  }
  return 0;
}