#include<bits/stdc++.h>
using namespace std ;
int read(){
char ch = getchar() ; int ans = 0 , f = 1 ;
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1 ; ch = getchar() ; }
while(ch >= '0' && ch <= '9'){ ans = (ans * 10) + ch - '0'; ch = getchar() ; }
return ans * f ;
}
#define maxn 400010
#define int long long
#define kkk signed main
#define mem(x) memset(x , 0 , sizeof(x))
#define lc o << 1
#define rc (o << 1) | 1
int fa[maxn][26] , deep[maxn] , top[maxn] , siz[maxn] , w[maxn] , son[maxn] , cloc , valt[maxn];
vector<int> G[maxn] ;
inline void addedge(int u , int v){
G[u].push_back(v) ; G[v].push_back(u) ; return ;
}
inline int MIN(int a , int b){
return a >= b ? b : a ;
}
int n , m , churt , nowrt , opt;
int val[maxn] ;
int INF = 2147493649 ;
inline void dfs1(int u , int f , int dep){
fa[u][0] = f ; deep[u] = dep ; int maxson = 0 ; siz[u]++;
for(int i = 1 ; i <= 25 ; i++)
fa[u][i] = fa[fa[u][i - 1]][i - 1] ;
for(int i = 0 ; i < G[u].size() ; i++){
int to = G[u][i] ;
if(to == f) continue ;
dfs1(to , u , dep + 1) ;
siz[u] += siz[to] ;
if(siz[to] > maxson) son[u] = to , maxson = siz[to] ;
}
return ;
}
inline void dfs2(int u , int tp , int f){
top[u] = tp ; w[u] = ++cloc ;
if(son[u]) dfs2(son[u] , tp , u) ;
for(int i = 0 ; i < G[u].size() ; i++){
int to = G[u][i] ;
if(to == f || to == son[u]) continue ;
dfs2(to , to , u) ;
}
}
int mmin[maxn] , changed[maxn];
inline void pushup(int o){
mmin[o] = min(mmin[lc] , mmin[rc]) ;
return ;
}
inline void build(int o , int l , int r){
if(l == r){
mmin[o] = valt[l];
// printf("valt[%lld] : %lld\n" , l , valt[l]) ;
return ;
}
int mid = (l + r) >> 1 ;
build(lc , l , mid) ; build(rc , mid + 1 , r) ;
pushup(o);
return ;
}
inline void pushdown(int o){
mmin[lc] = mmin[rc] = changed[o] ;
changed[lc] = changed[rc] = changed[o] ;
changed[o] = 0 ;
return ;
}
inline void change(int o , int l , int r , int ql , int qr , int k){
if(l > qr || r < ql) return ;
if(l >= ql && r <= qr){
mmin[o] = k ;
changed[o] = k;
return ;
}
int mid = (l + r ) >> 1 ;
if(changed[o]) pushdown(o) ;
change(lc , l , mid , ql , qr , k) ;
change(rc , mid + 1 , r , ql , qr , k) ;
pushup(o) ;
return ;
}
inline int query(int o , int l, int r , int ql , int qr ){
// printf("l : %lld r : %lld\n" , l , r) ;
if(l > qr || r < ql) return INF;
if(ql <= l && qr >= r){
// printf("kl : %lld r : %lld\n" , l , r) ;
// printf("mmin : %lld\n" , mmin[o]) ;
return mmin[o] ;
}
if(changed[o])
pushdown(o) ;
int mid = (l + r) >> 1;
int sum = MIN(query(lc , l , mid ,ql , qr) , query(rc , mid + 1 , r , ql , qr)) ;
pushup(o) ; return sum ;
}
inline void upd(int u , int v , int k ){
while(top[u] != top[v]){
if(deep[top[u]] <= deep[top[v]]) swap(u , v) ;
change(1 , 1 , n , w[top[u]] , w[u] , k ) ;
u = fa[top[u]][0] ;
}
if(deep[u] <= deep[v]) swap(u , v) ;
change( 1 , 1 , n , w[v] , w[u] , k) ;
return ;
}
inline int getfa(int u , int T){
for(int i = 25 ; i >= 0 ; i--){
if(1 << i <= T) u = fa[u][i] , T -= (1 << i) ;
}
return u ;
}
int p , q ;
kkk(){
// freopen("test.in" , "r" , stdin) ;
// freopen("test.out" , "w" ,stdout) ;
n = read() ; m = read() ;
for(int i = 1 ; i < n ; i++){
int u = read() , v = read() ;
addedge(u , v) ;
}
for(int i = 1 ; i <= n ; i++) val[i] = read() ;
churt = nowrt = read() ;
dfs1(churt , 0 , 1 ) ;
dfs2(churt , churt , 0) ;
for(int i = 1 ; i <= n ; i++) valt[w[i]] = val[i] ;
// for(int i = 1 ; i <= n ; i++)
// printf("num : %lld w : %lld top : %lld fa : %lld son : %lld siz : %lld\n" , i , w[i] , top[i] , fa[i][0] , son[i] , siz[i]) ;
// cout << getfa(10 , 4) << endl ;
build(1 , 1 , n) ;
// cout << query(1 , 1 , n , w[2] , w[10]) << endl ;
// upd(2 , 10 , -1) ;
// cout << query(1 , 1, n , w[1] , w[10]) << endl ;
// cout << INF ;
while(m--){
opt = read() ;
if(opt == 1) {
nowrt = read() ;
}
else if(opt == 2) {
int x = read() , y = read() , v = read() ;
upd(x , y ,v) ;
}
else{
int x = read() , y ;
if(nowrt == churt) printf("%lld\n" , query(1 , 1 , n , w[x] , w[x] + siz[x] - 1)) ;
else if(x == nowrt) printf("%lld\n" , mmin[1]) ;
else if(deep[nowrt] > deep[x] && x == fa[y = getfa(nowrt , deep[nowrt] - deep[x] - 1)][0]){
p = query(1 , 1 , n ,1 , w[y] - 1 ) ;
if(w[y] + siz[y] <= n) q = query(1 , 1 , n , w[y] + siz[x] , n) ;
else q = INF ;
printf("%lld\n" , min(p , q)) ;
}
else printf("%lld\n" , query(1 , 1 , n , w[x] , w[x] + siz[x] - 1)) ;
}
}
// printf("%lld\n" , query(1 , 1 , n , 1 , 7)) ;
return 0 ;
}
我的想法就是以最开始给的根来做树刨, 然后剩下就和其他人的差不多了, 但是不知道为什么wa了5个点
我仔细核对了每一个函数,似乎都没有问题。。。(一开始pushdown和别人还不一样,也改了)
所以到底哪里有问题呢