样例过了但是0分 玄关
查看原帖
样例过了但是0分 玄关
701408
lao_wang楼主2023/12/30 14:32

新手上路请大佬们多多指教

#include<bits/stdc++.h>
#define int long long
using namespace std ;
int n , m , dfs[123456] , top[123456] , dep[123456] , sz[123456] , son[123456] , fa[123456] , tot=0 , before[123456] , a[123456] ;
vector<int> e[123456] ;
struct node{
	int sum=0 , l=0 , r=0 , lazy=0 , lc , rc ;
}tree[912345];
void dfs1(int num,int f){
	fa[num] = f ;
	dep[num] = dep[f]+1 ;
	sz[num] = 1 ;
	for(auto x:e[num]){
		if(x==f) continue ;
		dfs1(x,num) ;
		sz[num] += sz[x] ;
		if(!son[num]||sz[son[num]]<sz[x]) son[num] = x ;
	}
}
void dfs2(int num,int head){
	dfs[num] = ++tot ;
	before[tot] = num ;
	top[num] = head ;
	if(son[num]) dfs2(son[num],head) ;
	for(auto x:e[num]){
		if(x==fa[num]||x==son[num]) continue ;
		dfs2(x,x) ;
	}
}
void push_up(int num){
	if(tree[num<<1].rc==tree[num<<1|1].lc)
		tree[num].sum = tree[num<<1].sum+tree[num<<1|1].sum-1 ;
	else
		tree[num].sum = tree[num<<1].sum+tree[num<<1|1].sum ;
	tree[num].lc = tree[num<<1].lc ;
	tree[num].rc = tree[num<<1|1].rc ;
}
void push_down(int num){
	if(!tree[num].lazy) return ;
	tree[num<<1].lc = tree[num<<1|1].lc = tree[num<<1].rc = tree[num<<1|1].rc = tree[num].lazy ;
	tree[num<<1].sum = tree[num<<1|1].sum = 1 ;
	tree[num<<1].lazy = tree[num<<1|1].lazy = tree[num].lazy ;
	tree[num].lazy = 0 ;
}
void made(int num,int l,int r){
	tree[num].l = l ;
	tree[num].r = r ;
	if(l==r){
		tree[num].sum = 1 ;
		tree[num].lc = tree[num].rc = a[before[l]] ;
		return ;
	}
	made(num<<1,l,(l+r)>>1) ;
	made(num<<1|1,((l+r)>>1)+1,r) ;
	push_up(num) ;
}
void change(int num,int l,int r,int v){
	if(tree[num].l>=l&&r>=tree[num].r){
		tree[num].sum = 1;
		tree[num].lc = tree[num].rc = v ; 
		tree[num].lazy = v ;
		return ;
	}
	push_down(num) ;
	int mid=(tree[num].l+tree[num].r)>>1 ;
	if(mid>=l) change(num<<1,l,r,v) ; 
	if(mid<r) change(num<<1|1,l,r,v) ;
}
node ask(int num,int l,int r){
	if(tree[num].l>=l&&r>=tree[num].r)
		return tree[num] ;
	push_down(num) ;
	int mid=(tree[num].l+tree[num].r)>>1 ;
	if(r<=mid) return ask(num<<1,l,r) ;
	else if(l>mid) return ask(num<<1|1,l,r) ;
	else {
		node L=ask(num<<1,l,r) ;
		node R=ask(num<<1|1,l,r) ;
		node ans ;
		if(L.rc==R.rc) ans.sum = L.sum+R.sum-1 ;
		else ans.sum = L.sum+R.sum ;
		ans.lc = L.lc ;
		ans.rc = R.rc ;
		return ans ;
	}
}
void LCA_change(int x,int y,int v){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y) ;
		change(1,dfs[top[x]],dfs[x],v) ;
		x = fa[top[x]] ;
	}
	if(dep[x]>dep[y]) swap(x,y) ;
	change(1,dfs[x],dfs[y],v) ;
}
int LCA_sum(int x,int y){
	node L , R ;
	L.lc = L.rc = R.lc = R.rc = 0 ;
	int ans=0 ;
	while(top[x]!=top[y]){
		if(dep[top[x]]>dep[top[y]]){
			node temp=ask(1,dfs[top[x]],dfs[x]) ;
			if(L.rc==temp.lc) L.sum += temp.sum-1 ;
			else L.sum += temp.sum ;
			L.rc = temp.rc ;
			x = fa[top[x]] ;
		}else{
			node temp=ask(1,dfs[top[y]],dfs[y]) ;
			if(R.lc==temp.rc) R.sum += temp.sum-1 ;
			else R.sum += temp.sum ;
			R.lc = temp.lc ;
			y  = fa[top[y]] ;
		}
	}
	if(dep[x]>dep[y]){
		node temp=ask(1,dfs[y],dfs[x]) ;
		if(L.rc==temp.lc) L.sum += temp.sum-1 ;
		else L.sum += temp.sum ;
		L.rc = temp.rc ;
	}else if(dep[x]<dep[y]){
		node temp=ask(1,dfs[x],dfs[y]) ;
		if(R.lc==temp.rc) R.sum += temp.sum-1 ;
		else R.sum += temp.sum ;
		R.lc = temp.lc ;
	}
	if(L.rc==R.lc) ans = L.sum+R.sum-1 ;
	else ans = L.sum+R.sum ; 
	return ans ;
}
signed main(){
	cin >> n >> m ;
	for(int i=1;i<=n;i++)
		scanf("%lld",a+i) ;
	for(int i=1;i<n;i++){
		int u , v ;
		scanf("%lld%lld",&u,&v) ;
		e[u].push_back(v) ;
		e[v].push_back(u) ;
	}
	dfs1(1,0) ;
	dfs2(1,1) ;
	made(1,1,n) ;
	for(int i=1;i<=m;i++){
		char s ;
		int a , b , c ;
		cin >> s ;
		scanf("%lld%lld",&a,&b) ;
		if(s=='C'){
			scanf("%lld",&c) ;
			LCA_change(a,b,c) ;
		}else{
			printf("%lld\n",LCA_sum(a,b)) ;
		}
	}
	return 0 ;
}
2023/12/30 14:32
加载中...