50分求助,调了一个下午了
查看原帖
50分求助,调了一个下午了
246800
wocaicai楼主2020/8/16 20:51
#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和别人还不一样,也改了)

所以到底哪里有问题呢

评测记录

2020/8/16 20:51
加载中...