spoj375樹鏈剖分模板

題意:

    對於一顆樹,兩種操作(1)修改某邊權(2)查詢兩點間最大邊權

解:樹鏈剖分

代碼(200ms):

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<ctime>
#include<queue>
#define For(i,j,k) for(register int i=(j);i<=(int)k;i++)
#define Forr(i,j,k) for(register int i=(j);i>=(int)k;i--)
#define Rep(i,u) for(register int i=Begin[(u)],v=to[i];i;i=Next[i],v=to[i])
#define Set(a,b) memset((a),b,sizeof(a))
using namespace std;
const int N=10010,E=20010;
int Begin[N],Next[E],to[E],fa[N],siz[N],son[N],dep[N],w[N],e=1,top[N],cnt,n;
int d[N][3];
void read(int &x){
	x=0;char c=getchar();int f(0);
	while(c<'0'||c>'9'){c=getchar();if(c=='-')f=1;}
	while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();if(f)x=-x;
}
inline void add(int x,int y){to[++e]=y,Next[e]=Begin[x],Begin[x]=e;}
struct zkwtree{
	int T[N<<2],M;
	inline void clear(){Set(T,0);}
	inline void pushup(int x){T[x]=max(T[x<<1],T[x<<1|1]);}
	void Build(){for(M=1;M<=n+1;M<<=1);}
	void add(int x,int v){for(T[x+=M]=v,x>>=1;x;x>>=1)pushup(x);}
	int query(int s,int t){
		int ret=-0x3f3f3f3f;
		for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){
			if(~s&1)ret=max(ret,T[s^1]);
			if(t&1)ret=max(ret,T[t^1]);
		}
		return ret;
	}
}t;
void dfs1(int u,int d){
	siz[u]=1;dep[u]=d;
	Rep(i,u)
		if(fa[u]!=v){
			fa[v]=u,dfs1(v,d+1),siz[u]+=siz[v];
			if(siz[v]>siz[son[u]])son[u]=v;
		}
} 
void dfs2(int u,int tp){
	top[u]=tp,w[u]=++cnt;
	if(son[u])dfs2(son[u],top[u]);
	Rep(i,u)
		if(son[u]!=v&&fa[u]!=v)
			dfs2(v,v);
}
void init(){
	read(n);
	Set(son,0),Set(Begin,0),Set(fa,0),e=1,cnt=0;
	For(i,1,n-1){
		read(d[i][0]),read(d[i][1]),read(d[i][2]);
		add(d[i][0],d[i][1]),add(d[i][1],d[i][0]);
	}
	dfs1(1,1);dfs2(1,1);
	t.clear();
	t.Build();
	For(i,1,n-1){
		if(dep[d[i][0]]>dep[d[i][1]])swap(d[i][0],d[i][1]);
		t.add(w[d[i][1]],d[i][2]);
	}
}
int Max(int x,int y){
	int tmp=-0x3f3f3f3f;
	for(;top[x]!=top[y];){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		tmp=max(tmp,t.query(w[top[x]],w[x]));
		x=fa[top[x]];
	}
	if (x==y)return tmp;
	if (dep[x]>dep[y])swap(x,y);
	return max(tmp,t.query(w[x]+1,w[y]));
}
void solve(){
	char s[10];
	while(scanf("%s",s)!=EOF){
		int x,y;
		if (s[0]=='D')break;
		read(x),read(y);
		if (s[0]!='Q')t.add(w[d[x][1]],y);
		else printf("%d\n",Max(x,y));
	}
}
int main(){
	int _;
	for(read(_);_;_--){
		init();
		solve();
	}
	return 0;
} 


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