BZOJ 3083: 遙遠的國度(codevs 4804)【鏈剖序+線段樹

……喵的WA了兩把,第一把是……倍增查詢是否爲lca的時候……忘記賦值anc[i][0] = father[i]了………………

第二把……………………我……INF開小了…………GGGGGGG

#include<bits/stdc++.h>
#define MAXN 100005
#define INF INT_MAX
using namespace std;	int n,m;
inline int read(){
	char ch = getchar();
	while((ch^'-')&&!isdigit(ch))	ch = getchar();
	int rtn = 0 , f = 1;
	if(ch=='-')	f = -1 , ch = getchar();
	while(isdigit(ch))	rtn = rtn*10 + ch - '0' , ch = getchar();
	return f*rtn;
}

int root;

struct t1{
	int to,nxt;
}edge[MAXN<<1];	int cnt_edge = 0;
int fst[MAXN];
void addedge(int x,int y){
	edge[++cnt_edge].to = y;
	edge[cnt_edge].nxt = fst[x];
	fst[x] = cnt_edge;
	
	edge[++cnt_edge].to = x;
	edge[cnt_edge].nxt = fst[y];
	fst[y] = cnt_edge;
}

int fth[MAXN] , siz[MAXN] , son[MAXN] , top[MAXN];
int dpt[MAXN] , anc[MAXN][18];
int val[MAXN];

void dfs1(int now){
	siz[now] = 1;
	for(int i=1;i<18;++i)	anc[now][i] = anc[ anc[now][i-1] ][i-1];	
	for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
		int aim = edge[tmp].to;
		if(aim==fth[now])	continue;
		fth[aim] = anc[aim][0] = now;
		dpt[aim] = dpt[now]+1;
		dfs1(aim);
		siz[now] += siz[aim];
		if(siz[aim] > siz[son[now]])	son[now] = aim;
	}
}

int dfn[MAXN] , idf[MAXN] , cnt_dfs = 0;

void dfs2(int now,int tp){
	top[now] = tp;
	dfn[now] = ++cnt_dfs;
	idf[cnt_dfs] = now;
	if(son[now])	dfs2(son[now],tp);
	for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
		int aim = edge[tmp].to;
		if(aim==fth[now]||aim==son[now])	continue;
		dfs2(aim,aim);
	}
}

int dt[MAXN<<2] , tag[MAXN<<2];
void build(int now,int l,int r){
	tag[now] = -1;
	if(l==r)	return void(dt[now] = val[idf[l]]); 
	int mid = (l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	dt[now] = min(dt[now<<1] , dt[now<<1|1]);
}

inline void pushdown(int now){
	dt[now<<1] = tag[now<<1] = tag[now];
	dt[now<<1|1] = tag[now<<1|1] = tag[now];
	tag[now] = -1;
}

int inqry(int now,int l,int r,int L,int R){
	if(L<=l&&r<=R)	return dt[now];
	if(~tag[now])	pushdown(now);
	int mid = (l+r)>>1;
	int tmp = INF;
	if(L<=mid)	tmp = inqry(now<<1,l,mid,L,R);
	if(mid<R)	tmp = min(tmp , inqry(now<<1|1,mid+1,r,L,R));
	return tmp;
}

void modify(int now,int l,int r,int L,int R,int v){
	if(L<=l&&r<=R)	return void(dt[now] = tag[now] = v);
	if(~tag[now])	pushdown(now);
	int mid = (l+r)>>1;
	if(L<=mid)	modify(now<<1,l,mid,L,R,v);
	if(mid<R)	modify(now<<1|1,mid+1,r,L,R,v);
	dt[now] = min(dt[now<<1] , dt[now<<1|1]);
}

inline void work_modify_chain(int u,int v,int k){
	while(top[u]^top[v]){
		if(dpt[top[u]] > dpt[top[v]]){
			modify(1,1,n,dfn[top[u]] , dfn[u],k);
			u = fth[top[u]];
		}
		else{
			modify(1,1,n,dfn[top[v]] , dfn[v],k);
			v = fth[top[v]];
		}
	}
	if(dpt[u]<dpt[v])
		modify(1,1,n,dfn[u],dfn[v],k);
	else	modify(1,1,n,dfn[v],dfn[u],k);
}

int AIM;

inline bool is_ANC(int u,int v){
	if(dpt[u]>=dpt[v])	return 0;
	for(int dlt = dpt[v] - dpt[u] - 1 , i = 0;i<18;++i)
		if(dlt&(1<<i))
			v = anc[v][i];
	if(u==fth[v])	return AIM = v,1;
	return 0;
}

int cnttt = 0;

inline void work_ask_subtree(int x){
	++cnttt;
	if(x==root){
		printf("%d\n",dt[1]);
		return ;
	}
	if(is_ANC(x,root)){
		int ans = INF;
		if(dfn[AIM]>1)	ans = inqry(1,1,n,1,dfn[AIM] - 1);
		if(dfn[AIM]<n)	ans = min(ans,inqry(1,1,n,dfn[AIM]+siz[AIM],n));
		printf("%d\n",ans);
	}
	else
		printf("%d\n",inqry(1,1,n,dfn[x],dfn[x]+siz[x]-1));
}

int opt;
int main(){
	freopen("1.in","r",stdin);
	freopen("1.out","w",stdout);
	
	n = read() , m = read();
	for(int i=1;i<n;++i)
		addedge(read(),read());
	for(int i=1;i<=n;++i)	val[i] = read();
	root = read();
	
	dpt[root] = 1;
	dfs1(root);
	dfs2(root,root);
	
	build(1,1,n);
	
	while(m--){
		opt = read();
		if(opt==1)
			root = read();
		else{
			if(opt==2){
				int x,y,z;
				x = read() , y = read() , z = read();
				work_modify_chain(x,y,z);
			}
			else
				work_ask_subtree(read());
		}
	}
	
	return 0;
} 


發佈了123 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章