代码
#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 ( ) { 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 ;
}